| author | |
| committer | |
| log | 5140f2726ae6e09381d9d44a72626dfe319f068b |
| tree | b2163e1439be4858c8e11b7d210ab91e262ab761 |
| parent | 341857e5cd4fd4453cf9c7d1a6679feb66710d84 |
| parent | 513254956525f8f970e972f6973ab4df0b19d06a |
| signature |
Follow-up to #1941440 files changed, 2016 insertions(+), 2706 deletions(-)
CMakeLists.txt+2-1| ... | @@ -526,7 +526,6 @@ set(ZIG_STAGE2_SOURCES | ... | @@ -526,7 +526,6 @@ set(ZIG_STAGE2_SOURCES |
| 526 | "${CMAKE_SOURCE_DIR}/src/Package/Fetch.zig" | 526 | "${CMAKE_SOURCE_DIR}/src/Package/Fetch.zig" |
| 527 | "${CMAKE_SOURCE_DIR}/src/RangeSet.zig" | 527 | "${CMAKE_SOURCE_DIR}/src/RangeSet.zig" |
| 528 | "${CMAKE_SOURCE_DIR}/src/Sema.zig" | 528 | "${CMAKE_SOURCE_DIR}/src/Sema.zig" |
| 529 | "${CMAKE_SOURCE_DIR}/src/TypedValue.zig" | ||
| 530 | "${CMAKE_SOURCE_DIR}/src/Value.zig" | 529 | "${CMAKE_SOURCE_DIR}/src/Value.zig" |
| 531 | "${CMAKE_SOURCE_DIR}/src/arch/aarch64/CodeGen.zig" | 530 | "${CMAKE_SOURCE_DIR}/src/arch/aarch64/CodeGen.zig" |
| 532 | "${CMAKE_SOURCE_DIR}/src/arch/aarch64/Emit.zig" | 531 | "${CMAKE_SOURCE_DIR}/src/arch/aarch64/Emit.zig" |
| ... | @@ -634,9 +633,11 @@ set(ZIG_STAGE2_SOURCES | ... | @@ -634,9 +633,11 @@ set(ZIG_STAGE2_SOURCES |
| 634 | "${CMAKE_SOURCE_DIR}/src/main.zig" | 633 | "${CMAKE_SOURCE_DIR}/src/main.zig" |
| 635 | "${CMAKE_SOURCE_DIR}/src/mingw.zig" | 634 | "${CMAKE_SOURCE_DIR}/src/mingw.zig" |
| 636 | "${CMAKE_SOURCE_DIR}/src/musl.zig" | 635 | "${CMAKE_SOURCE_DIR}/src/musl.zig" |
| 636 | "${CMAKE_SOURCE_DIR}/src/mutable_value.zig" | ||
| 637 | "${CMAKE_SOURCE_DIR}/src/print_air.zig" | 637 | "${CMAKE_SOURCE_DIR}/src/print_air.zig" |
| 638 | "${CMAKE_SOURCE_DIR}/src/print_env.zig" | 638 | "${CMAKE_SOURCE_DIR}/src/print_env.zig" |
| 639 | "${CMAKE_SOURCE_DIR}/src/print_targets.zig" | 639 | "${CMAKE_SOURCE_DIR}/src/print_targets.zig" |
| 640 | "${CMAKE_SOURCE_DIR}/src/print_value.zig" | ||
| 640 | "${CMAKE_SOURCE_DIR}/src/print_zir.zig" | 641 | "${CMAKE_SOURCE_DIR}/src/print_zir.zig" |
| 641 | "${CMAKE_SOURCE_DIR}/src/register_manager.zig" | 642 | "${CMAKE_SOURCE_DIR}/src/register_manager.zig" |
| 642 | "${CMAKE_SOURCE_DIR}/src/target.zig" | 643 | "${CMAKE_SOURCE_DIR}/src/target.zig" |
src/Compilation.zig+1-18| ... | @@ -102,7 +102,6 @@ link_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{}, | ... | @@ -102,7 +102,6 @@ link_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{}, |
| 102 | lld_errors: std.ArrayListUnmanaged(LldError) = .{}, | 102 | lld_errors: std.ArrayListUnmanaged(LldError) = .{}, |
| 103 | 103 | ||
| 104 | work_queue: std.fifo.LinearFifo(Job, .Dynamic), | 104 | work_queue: std.fifo.LinearFifo(Job, .Dynamic), |
| 105 | anon_work_queue: std.fifo.LinearFifo(Job, .Dynamic), | ||
| 106 | 105 | ||
| 107 | /// These jobs are to invoke the Clang compiler to create an object file, which | 106 | /// These jobs are to invoke the Clang compiler to create an object file, which |
| 108 | /// gets linked with the Compilation. | 107 | /// gets linked with the Compilation. |
| ... | @@ -1417,7 +1416,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1417,7 +1416,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1417 | .emit_llvm_ir = options.emit_llvm_ir, | 1416 | .emit_llvm_ir = options.emit_llvm_ir, |
| 1418 | .emit_llvm_bc = options.emit_llvm_bc, | 1417 | .emit_llvm_bc = options.emit_llvm_bc, |
| 1419 | .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa), | 1418 | .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa), |
| 1420 | .anon_work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa), | ||
| 1421 | .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa), | 1419 | .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa), |
| 1422 | .win32_resource_work_queue = if (build_options.only_core_functionality) {} else std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa), | 1420 | .win32_resource_work_queue = if (build_options.only_core_functionality) {} else std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa), |
| 1423 | .astgen_work_queue = std.fifo.LinearFifo(*Module.File, .Dynamic).init(gpa), | 1421 | .astgen_work_queue = std.fifo.LinearFifo(*Module.File, .Dynamic).init(gpa), |
| ... | @@ -1840,7 +1838,6 @@ pub fn destroy(comp: *Compilation) void { | ... | @@ -1840,7 +1838,6 @@ pub fn destroy(comp: *Compilation) void { |
| 1840 | if (comp.module) |zcu| zcu.deinit(); | 1838 | if (comp.module) |zcu| zcu.deinit(); |
| 1841 | comp.cache_use.deinit(); | 1839 | comp.cache_use.deinit(); |
| 1842 | comp.work_queue.deinit(); | 1840 | comp.work_queue.deinit(); |
| 1843 | comp.anon_work_queue.deinit(); | ||
| 1844 | comp.c_object_work_queue.deinit(); | 1841 | comp.c_object_work_queue.deinit(); |
| 1845 | if (!build_options.only_core_functionality) { | 1842 | if (!build_options.only_core_functionality) { |
| 1846 | comp.win32_resource_work_queue.deinit(); | 1843 | comp.win32_resource_work_queue.deinit(); |
| ... | @@ -3354,18 +3351,11 @@ pub fn performAllTheWork( | ... | @@ -3354,18 +3351,11 @@ pub fn performAllTheWork( |
| 3354 | mod.sema_prog_node = undefined; | 3351 | mod.sema_prog_node = undefined; |
| 3355 | }; | 3352 | }; |
| 3356 | 3353 | ||
| 3357 | // In this main loop we give priority to non-anonymous Decls in the work queue, so | ||
| 3358 | // that they can establish references to anonymous Decls, setting alive=true in the | ||
| 3359 | // backend, preventing anonymous Decls from being prematurely destroyed. | ||
| 3360 | while (true) { | 3354 | while (true) { |
| 3361 | if (comp.work_queue.readItem()) |work_item| { | 3355 | if (comp.work_queue.readItem()) |work_item| { |
| 3362 | try processOneJob(comp, work_item, main_progress_node); | 3356 | try processOneJob(comp, work_item, main_progress_node); |
| 3363 | continue; | 3357 | continue; |
| 3364 | } | 3358 | } |
| 3365 | if (comp.anon_work_queue.readItem()) |work_item| { | ||
| 3366 | try processOneJob(comp, work_item, main_progress_node); | ||
| 3367 | continue; | ||
| 3368 | } | ||
| 3369 | if (comp.module) |zcu| { | 3359 | if (comp.module) |zcu| { |
| 3370 | // If there's no work queued, check if there's anything outdated | 3360 | // If there's no work queued, check if there's anything outdated |
| 3371 | // which we need to work on, and queue it if so. | 3361 | // which we need to work on, and queue it if so. |
| ... | @@ -3413,14 +3403,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v | ... | @@ -3413,14 +3403,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v |
| 3413 | 3403 | ||
| 3414 | assert(decl.has_tv); | 3404 | assert(decl.has_tv); |
| 3415 | 3405 | ||
| 3416 | if (decl.alive) { | 3406 | try module.linkerUpdateDecl(decl_index); |
| 3417 | try module.linkerUpdateDecl(decl_index); | ||
| 3418 | return; | ||
| 3419 | } | ||
| 3420 | |||
| 3421 | // Instead of sending this decl to the linker, we actually will delete it | ||
| 3422 | // because we found out that it in fact was never referenced. | ||
| 3423 | module.deleteUnusedDecl(decl_index); | ||
| 3424 | return; | 3407 | return; |
| 3425 | }, | 3408 | }, |
| 3426 | } | 3409 | } |
src/InternPool.zig-5| ... | @@ -6581,7 +6581,6 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey) | ... | @@ -6581,7 +6581,6 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey) |
| 6581 | generic_owner, | 6581 | generic_owner, |
| 6582 | func_index, | 6582 | func_index, |
| 6583 | func_extra_index, | 6583 | func_extra_index, |
| 6584 | func_ty, | ||
| 6585 | arg.alignment, | 6584 | arg.alignment, |
| 6586 | arg.section, | 6585 | arg.section, |
| 6587 | ); | 6586 | ); |
| ... | @@ -6711,7 +6710,6 @@ pub fn getFuncInstanceIes( | ... | @@ -6711,7 +6710,6 @@ pub fn getFuncInstanceIes( |
| 6711 | generic_owner, | 6710 | generic_owner, |
| 6712 | func_index, | 6711 | func_index, |
| 6713 | func_extra_index, | 6712 | func_extra_index, |
| 6714 | func_ty, | ||
| 6715 | arg.alignment, | 6713 | arg.alignment, |
| 6716 | arg.section, | 6714 | arg.section, |
| 6717 | ); | 6715 | ); |
| ... | @@ -6723,7 +6721,6 @@ fn finishFuncInstance( | ... | @@ -6723,7 +6721,6 @@ fn finishFuncInstance( |
| 6723 | generic_owner: Index, | 6721 | generic_owner: Index, |
| 6724 | func_index: Index, | 6722 | func_index: Index, |
| 6725 | func_extra_index: u32, | 6723 | func_extra_index: u32, |
| 6726 | func_ty: Index, | ||
| 6727 | alignment: Alignment, | 6724 | alignment: Alignment, |
| 6728 | section: OptionalNullTerminatedString, | 6725 | section: OptionalNullTerminatedString, |
| 6729 | ) Allocator.Error!Index { | 6726 | ) Allocator.Error!Index { |
| ... | @@ -6735,7 +6732,6 @@ fn finishFuncInstance( | ... | @@ -6735,7 +6732,6 @@ fn finishFuncInstance( |
| 6735 | .src_line = fn_owner_decl.src_line, | 6732 | .src_line = fn_owner_decl.src_line, |
| 6736 | .has_tv = true, | 6733 | .has_tv = true, |
| 6737 | .owns_tv = true, | 6734 | .owns_tv = true, |
| 6738 | .ty = @import("type.zig").Type.fromInterned(func_ty), | ||
| 6739 | .val = @import("Value.zig").fromInterned(func_index), | 6735 | .val = @import("Value.zig").fromInterned(func_index), |
| 6740 | .alignment = alignment, | 6736 | .alignment = alignment, |
| 6741 | .@"linksection" = section, | 6737 | .@"linksection" = section, |
| ... | @@ -6744,7 +6740,6 @@ fn finishFuncInstance( | ... | @@ -6744,7 +6740,6 @@ fn finishFuncInstance( |
| 6744 | .zir_decl_index = fn_owner_decl.zir_decl_index, | 6740 | .zir_decl_index = fn_owner_decl.zir_decl_index, |
| 6745 | .is_pub = fn_owner_decl.is_pub, | 6741 | .is_pub = fn_owner_decl.is_pub, |
| 6746 | .is_exported = fn_owner_decl.is_exported, | 6742 | .is_exported = fn_owner_decl.is_exported, |
| 6747 | .alive = true, | ||
| 6748 | .kind = .anon, | 6743 | .kind = .anon, |
| 6749 | }); | 6744 | }); |
| 6750 | errdefer ip.destroyDecl(gpa, decl_index); | 6745 | errdefer ip.destroyDecl(gpa, decl_index); |
src/Module.zig+56-209| ... | @@ -22,7 +22,6 @@ const Compilation = @import("Compilation.zig"); | ... | @@ -22,7 +22,6 @@ const Compilation = @import("Compilation.zig"); |
| 22 | const Cache = std.Build.Cache; | 22 | const Cache = std.Build.Cache; |
| 23 | const Value = @import("Value.zig"); | 23 | const Value = @import("Value.zig"); |
| 24 | const Type = @import("type.zig").Type; | 24 | const Type = @import("type.zig").Type; |
| 25 | const TypedValue = @import("TypedValue.zig"); | ||
| 26 | const Package = @import("Package.zig"); | 25 | const Package = @import("Package.zig"); |
| 27 | const link = @import("link.zig"); | 26 | const link = @import("link.zig"); |
| 28 | const Air = @import("Air.zig"); | 27 | const Air = @import("Air.zig"); |
| ... | @@ -330,9 +329,6 @@ const ValueArena = struct { | ... | @@ -330,9 +329,6 @@ const ValueArena = struct { |
| 330 | 329 | ||
| 331 | pub const Decl = struct { | 330 | pub const Decl = struct { |
| 332 | name: InternPool.NullTerminatedString, | 331 | name: InternPool.NullTerminatedString, |
| 333 | /// The most recent Type of the Decl after a successful semantic analysis. | ||
| 334 | /// Populated when `has_tv`. | ||
| 335 | ty: Type, | ||
| 336 | /// The most recent Value of the Decl after a successful semantic analysis. | 332 | /// The most recent Value of the Decl after a successful semantic analysis. |
| 337 | /// Populated when `has_tv`. | 333 | /// Populated when `has_tv`. |
| 338 | val: Value, | 334 | val: Value, |
| ... | @@ -397,15 +393,6 @@ pub const Decl = struct { | ... | @@ -397,15 +393,6 @@ pub const Decl = struct { |
| 397 | is_pub: bool, | 393 | is_pub: bool, |
| 398 | /// Whether the corresponding AST decl has a `export` keyword. | 394 | /// Whether the corresponding AST decl has a `export` keyword. |
| 399 | is_exported: bool, | 395 | is_exported: bool, |
| 400 | /// Flag used by garbage collection to mark and sweep. | ||
| 401 | /// Decls which correspond to an AST node always have this field set to `true`. | ||
| 402 | /// Anonymous Decls are initialized with this field set to `false` and then it | ||
| 403 | /// is the responsibility of machine code backends to mark it `true` whenever | ||
| 404 | /// a `decl_ref` Value is encountered that points to this Decl. | ||
| 405 | /// When the `codegen_decl` job is encountered in the main work queue, if the | ||
| 406 | /// Decl is marked alive, then it sends the Decl to the linker. Otherwise it | ||
| 407 | /// deletes the Decl on the spot. | ||
| 408 | alive: bool, | ||
| 409 | /// If true `name` is already fully qualified. | 396 | /// If true `name` is already fully qualified. |
| 410 | name_fully_qualified: bool = false, | 397 | name_fully_qualified: bool = false, |
| 411 | /// What kind of a declaration is this. | 398 | /// What kind of a declaration is this. |
| ... | @@ -438,14 +425,6 @@ pub const Decl = struct { | ... | @@ -438,14 +425,6 @@ pub const Decl = struct { |
| 438 | return @as(i32, @bitCast(node_index)) - @as(i32, @bitCast(decl.src_node)); | 425 | return @as(i32, @bitCast(node_index)) - @as(i32, @bitCast(decl.src_node)); |
| 439 | } | 426 | } |
| 440 | 427 | ||
| 441 | pub fn tokSrcLoc(decl: Decl, token_index: Ast.TokenIndex) LazySrcLoc { | ||
| 442 | return .{ .token_offset = token_index - decl.srcToken() }; | ||
| 443 | } | ||
| 444 | |||
| 445 | pub fn nodeSrcLoc(decl: Decl, node_index: Ast.Node.Index) LazySrcLoc { | ||
| 446 | return LazySrcLoc.nodeOffset(decl.nodeIndexToRelative(node_index)); | ||
| 447 | } | ||
| 448 | |||
| 449 | pub fn srcLoc(decl: Decl, zcu: *Zcu) SrcLoc { | 428 | pub fn srcLoc(decl: Decl, zcu: *Zcu) SrcLoc { |
| 450 | return decl.nodeOffsetSrcLoc(0, zcu); | 429 | return decl.nodeOffsetSrcLoc(0, zcu); |
| 451 | } | 430 | } |
| ... | @@ -458,16 +437,6 @@ pub const Decl = struct { | ... | @@ -458,16 +437,6 @@ pub const Decl = struct { |
| 458 | }; | 437 | }; |
| 459 | } | 438 | } |
| 460 | 439 | ||
| 461 | pub fn srcToken(decl: Decl, zcu: *Zcu) Ast.TokenIndex { | ||
| 462 | const tree = &decl.getFileScope(zcu).tree; | ||
| 463 | return tree.firstToken(decl.src_node); | ||
| 464 | } | ||
| 465 | |||
| 466 | pub fn srcByteOffset(decl: Decl, zcu: *Zcu) u32 { | ||
| 467 | const tree = &decl.getFileScope(zcu).tree; | ||
| 468 | return tree.tokens.items(.start)[decl.srcToken()]; | ||
| 469 | } | ||
| 470 | |||
| 471 | pub fn renderFullyQualifiedName(decl: Decl, zcu: *Zcu, writer: anytype) !void { | 440 | pub fn renderFullyQualifiedName(decl: Decl, zcu: *Zcu, writer: anytype) !void { |
| 472 | if (decl.name_fully_qualified) { | 441 | if (decl.name_fully_qualified) { |
| 473 | try writer.print("{}", .{decl.name.fmt(&zcu.intern_pool)}); | 442 | try writer.print("{}", .{decl.name.fmt(&zcu.intern_pool)}); |
| ... | @@ -487,37 +456,16 @@ pub const Decl = struct { | ... | @@ -487,37 +456,16 @@ pub const Decl = struct { |
| 487 | zcu.namespacePtr(decl.src_namespace).fullyQualifiedName(zcu, decl.name); | 456 | zcu.namespacePtr(decl.src_namespace).fullyQualifiedName(zcu, decl.name); |
| 488 | } | 457 | } |
| 489 | 458 | ||
| 490 | pub fn typedValue(decl: Decl) error{AnalysisFail}!TypedValue { | 459 | pub fn typeOf(decl: Decl, zcu: *const Zcu) Type { |
| 491 | if (!decl.has_tv) return error.AnalysisFail; | ||
| 492 | return TypedValue{ .ty = decl.ty, .val = decl.val }; | ||
| 493 | } | ||
| 494 | |||
| 495 | pub fn internValue(decl: *Decl, zcu: *Zcu) Allocator.Error!InternPool.Index { | ||
| 496 | assert(decl.has_tv); | 460 | assert(decl.has_tv); |
| 497 | const ip_index = try decl.val.intern(decl.ty, zcu); | 461 | return decl.val.typeOf(zcu); |
| 498 | decl.val = Value.fromInterned(ip_index); | ||
| 499 | return ip_index; | ||
| 500 | } | 462 | } |
| 501 | 463 | ||
| 502 | pub fn isFunction(decl: Decl, zcu: *const Zcu) !bool { | 464 | /// Small wrapper for Sema to use over direct access to the `val` field. |
| 503 | const tv = try decl.typedValue(); | 465 | /// If the value is not populated, instead returns `error.AnalysisFail`. |
| 504 | return tv.ty.zigTypeTag(zcu) == .Fn; | 466 | pub fn valueOrFail(decl: Decl) error{AnalysisFail}!Value { |
| 505 | } | 467 | if (!decl.has_tv) return error.AnalysisFail; |
| 506 | 468 | return decl.val; | |
| 507 | /// If the Decl owns its value and it is a struct, return it, | ||
| 508 | /// otherwise null. | ||
| 509 | pub fn getOwnedStruct(decl: Decl, zcu: *Zcu) ?InternPool.Key.StructType { | ||
| 510 | if (!decl.owns_tv) return null; | ||
| 511 | if (decl.val.ip_index == .none) return null; | ||
| 512 | return zcu.typeToStruct(decl.val.toType()); | ||
| 513 | } | ||
| 514 | |||
| 515 | /// If the Decl owns its value and it is a union, return it, | ||
| 516 | /// otherwise null. | ||
| 517 | pub fn getOwnedUnion(decl: Decl, zcu: *Zcu) ?InternPool.LoadedUnionType { | ||
| 518 | if (!decl.owns_tv) return null; | ||
| 519 | if (decl.val.ip_index == .none) return null; | ||
| 520 | return zcu.typeToUnion(decl.val.toType()); | ||
| 521 | } | 469 | } |
| 522 | 470 | ||
| 523 | pub fn getOwnedFunction(decl: Decl, zcu: *Zcu) ?InternPool.Key.Func { | 471 | pub fn getOwnedFunction(decl: Decl, zcu: *Zcu) ?InternPool.Key.Func { |
| ... | @@ -590,7 +538,7 @@ pub const Decl = struct { | ... | @@ -590,7 +538,7 @@ pub const Decl = struct { |
| 590 | @tagName(decl.analysis), | 538 | @tagName(decl.analysis), |
| 591 | }); | 539 | }); |
| 592 | if (decl.has_tv) { | 540 | if (decl.has_tv) { |
| 593 | std.debug.print(" ty={} val={}", .{ decl.ty, decl.val }); | 541 | std.debug.print(" val={}", .{decl.val}); |
| 594 | } | 542 | } |
| 595 | std.debug.print("\n", .{}); | 543 | std.debug.print("\n", .{}); |
| 596 | } | 544 | } |
| ... | @@ -615,7 +563,7 @@ pub const Decl = struct { | ... | @@ -615,7 +563,7 @@ pub const Decl = struct { |
| 615 | pub fn getAlignment(decl: Decl, zcu: *Zcu) Alignment { | 563 | pub fn getAlignment(decl: Decl, zcu: *Zcu) Alignment { |
| 616 | assert(decl.has_tv); | 564 | assert(decl.has_tv); |
| 617 | if (decl.alignment != .none) return decl.alignment; | 565 | if (decl.alignment != .none) return decl.alignment; |
| 618 | return decl.ty.abiAlignment(zcu); | 566 | return decl.typeOf(zcu).abiAlignment(zcu); |
| 619 | } | 567 | } |
| 620 | 568 | ||
| 621 | /// Upgrade a `LazySrcLoc` to a `SrcLoc` based on the `Decl` provided. | 569 | /// Upgrade a `LazySrcLoc` to a `SrcLoc` based on the `Decl` provided. |
| ... | @@ -3525,10 +3473,8 @@ fn semaFile(mod: *Module, file: *File) SemaError!void { | ... | @@ -3525,10 +3473,8 @@ fn semaFile(mod: *Module, file: *File) SemaError!void { |
| 3525 | new_decl.src_line = 0; | 3473 | new_decl.src_line = 0; |
| 3526 | new_decl.is_pub = true; | 3474 | new_decl.is_pub = true; |
| 3527 | new_decl.is_exported = false; | 3475 | new_decl.is_exported = false; |
| 3528 | new_decl.ty = Type.type; | ||
| 3529 | new_decl.alignment = .none; | 3476 | new_decl.alignment = .none; |
| 3530 | new_decl.@"linksection" = .none; | 3477 | new_decl.@"linksection" = .none; |
| 3531 | new_decl.alive = true; // This Decl corresponds to a File and is therefore always alive. | ||
| 3532 | new_decl.analysis = .in_progress; | 3478 | new_decl.analysis = .in_progress; |
| 3533 | 3479 | ||
| 3534 | if (file.status != .success_zir) { | 3480 | if (file.status != .success_zir) { |
| ... | @@ -3594,7 +3540,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { | ... | @@ -3594,7 +3540,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { |
| 3594 | 3540 | ||
| 3595 | const old_has_tv = decl.has_tv; | 3541 | const old_has_tv = decl.has_tv; |
| 3596 | // The following values are ignored if `!old_has_tv` | 3542 | // The following values are ignored if `!old_has_tv` |
| 3597 | const old_ty = decl.ty; | 3543 | const old_ty = if (old_has_tv) decl.typeOf(mod) else undefined; |
| 3598 | const old_val = decl.val; | 3544 | const old_val = decl.val; |
| 3599 | const old_align = decl.alignment; | 3545 | const old_align = decl.alignment; |
| 3600 | const old_linksection = decl.@"linksection"; | 3546 | const old_linksection = decl.@"linksection"; |
| ... | @@ -3698,25 +3644,25 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { | ... | @@ -3698,25 +3644,25 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { |
| 3698 | const address_space_src: LazySrcLoc = .{ .node_offset_var_decl_addrspace = 0 }; | 3644 | const address_space_src: LazySrcLoc = .{ .node_offset_var_decl_addrspace = 0 }; |
| 3699 | const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = 0 }; | 3645 | const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = 0 }; |
| 3700 | const init_src: LazySrcLoc = .{ .node_offset_var_decl_init = 0 }; | 3646 | const init_src: LazySrcLoc = .{ .node_offset_var_decl_init = 0 }; |
| 3701 | const decl_tv = try sema.resolveFinalDeclValue(&block_scope, init_src, result_ref); | 3647 | const decl_val = try sema.resolveFinalDeclValue(&block_scope, init_src, result_ref); |
| 3648 | const decl_ty = decl_val.typeOf(mod); | ||
| 3702 | 3649 | ||
| 3703 | // Note this resolves the type of the Decl, not the value; if this Decl | 3650 | // Note this resolves the type of the Decl, not the value; if this Decl |
| 3704 | // is a struct, for example, this resolves `type` (which needs no resolution), | 3651 | // is a struct, for example, this resolves `type` (which needs no resolution), |
| 3705 | // not the struct itself. | 3652 | // not the struct itself. |
| 3706 | try sema.resolveTypeLayout(decl_tv.ty); | 3653 | try sema.resolveTypeLayout(decl_ty); |
| 3707 | 3654 | ||
| 3708 | if (decl.kind == .@"usingnamespace") { | 3655 | if (decl.kind == .@"usingnamespace") { |
| 3709 | if (!decl_tv.ty.eql(Type.type, mod)) { | 3656 | if (!decl_ty.eql(Type.type, mod)) { |
| 3710 | return sema.fail(&block_scope, ty_src, "expected type, found {}", .{ | 3657 | return sema.fail(&block_scope, ty_src, "expected type, found {}", .{ |
| 3711 | decl_tv.ty.fmt(mod), | 3658 | decl_ty.fmt(mod), |
| 3712 | }); | 3659 | }); |
| 3713 | } | 3660 | } |
| 3714 | const ty = decl_tv.val.toType(); | 3661 | const ty = decl_val.toType(); |
| 3715 | if (ty.getNamespace(mod) == null) { | 3662 | if (ty.getNamespace(mod) == null) { |
| 3716 | return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(mod)}); | 3663 | return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(mod)}); |
| 3717 | } | 3664 | } |
| 3718 | 3665 | ||
| 3719 | decl.ty = Type.fromInterned(InternPool.Index.type_type); | ||
| 3720 | decl.val = ty.toValue(); | 3666 | decl.val = ty.toValue(); |
| 3721 | decl.alignment = .none; | 3667 | decl.alignment = .none; |
| 3722 | decl.@"linksection" = .none; | 3668 | decl.@"linksection" = .none; |
| ... | @@ -3734,10 +3680,10 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { | ... | @@ -3734,10 +3680,10 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { |
| 3734 | var queue_linker_work = true; | 3680 | var queue_linker_work = true; |
| 3735 | var is_func = false; | 3681 | var is_func = false; |
| 3736 | var is_inline = false; | 3682 | var is_inline = false; |
| 3737 | switch (decl_tv.val.toIntern()) { | 3683 | switch (decl_val.toIntern()) { |
| 3738 | .generic_poison => unreachable, | 3684 | .generic_poison => unreachable, |
| 3739 | .unreachable_value => unreachable, | 3685 | .unreachable_value => unreachable, |
| 3740 | else => switch (ip.indexToKey(decl_tv.val.toIntern())) { | 3686 | else => switch (ip.indexToKey(decl_val.toIntern())) { |
| 3741 | .variable => |variable| { | 3687 | .variable => |variable| { |
| 3742 | decl.owns_tv = variable.decl == decl_index; | 3688 | decl.owns_tv = variable.decl == decl_index; |
| 3743 | queue_linker_work = decl.owns_tv; | 3689 | queue_linker_work = decl.owns_tv; |
| ... | @@ -3752,7 +3698,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { | ... | @@ -3752,7 +3698,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { |
| 3752 | .func => |func| { | 3698 | .func => |func| { |
| 3753 | decl.owns_tv = func.owner_decl == decl_index; | 3699 | decl.owns_tv = func.owner_decl == decl_index; |
| 3754 | queue_linker_work = false; | 3700 | queue_linker_work = false; |
| 3755 | is_inline = decl.owns_tv and decl_tv.ty.fnCallingConvention(mod) == .Inline; | 3701 | is_inline = decl.owns_tv and decl_ty.fnCallingConvention(mod) == .Inline; |
| 3756 | is_func = decl.owns_tv; | 3702 | is_func = decl.owns_tv; |
| 3757 | }, | 3703 | }, |
| 3758 | 3704 | ||
| ... | @@ -3760,8 +3706,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { | ... | @@ -3760,8 +3706,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { |
| 3760 | }, | 3706 | }, |
| 3761 | } | 3707 | } |
| 3762 | 3708 | ||
| 3763 | decl.ty = decl_tv.ty; | 3709 | decl.val = decl_val; |
| 3764 | decl.val = Value.fromInterned((try decl_tv.val.intern(decl_tv.ty, mod))); | ||
| 3765 | // Function linksection, align, and addrspace were already set by Sema | 3710 | // Function linksection, align, and addrspace were already set by Sema |
| 3766 | if (!is_func) { | 3711 | if (!is_func) { |
| 3767 | decl.alignment = blk: { | 3712 | decl.alignment = blk: { |
| ... | @@ -3784,7 +3729,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { | ... | @@ -3784,7 +3729,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { |
| 3784 | break :blk section.toOptional(); | 3729 | break :blk section.toOptional(); |
| 3785 | }; | 3730 | }; |
| 3786 | decl.@"addrspace" = blk: { | 3731 | decl.@"addrspace" = blk: { |
| 3787 | const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_tv.val.toIntern())) { | 3732 | const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) { |
| 3788 | .variable => .variable, | 3733 | .variable => .variable, |
| 3789 | .extern_func, .func => .function, | 3734 | .extern_func, .func => .function, |
| 3790 | else => .constant, | 3735 | else => .constant, |
| ... | @@ -3806,10 +3751,10 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { | ... | @@ -3806,10 +3751,10 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { |
| 3806 | decl.analysis = .complete; | 3751 | decl.analysis = .complete; |
| 3807 | 3752 | ||
| 3808 | const result: SemaDeclResult = if (old_has_tv) .{ | 3753 | const result: SemaDeclResult = if (old_has_tv) .{ |
| 3809 | .invalidate_decl_val = !decl.ty.eql(old_ty, mod) or | 3754 | .invalidate_decl_val = !decl_ty.eql(old_ty, mod) or |
| 3810 | !decl.val.eql(old_val, decl.ty, mod) or | 3755 | !decl.val.eql(old_val, decl_ty, mod) or |
| 3811 | is_inline != old_is_inline, | 3756 | is_inline != old_is_inline, |
| 3812 | .invalidate_decl_ref = !decl.ty.eql(old_ty, mod) or | 3757 | .invalidate_decl_ref = !decl_ty.eql(old_ty, mod) or |
| 3813 | decl.alignment != old_align or | 3758 | decl.alignment != old_align or |
| 3814 | decl.@"linksection" != old_linksection or | 3759 | decl.@"linksection" != old_linksection or |
| 3815 | decl.@"addrspace" != old_addrspace or | 3760 | decl.@"addrspace" != old_addrspace or |
| ... | @@ -3819,11 +3764,11 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { | ... | @@ -3819,11 +3764,11 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { |
| 3819 | .invalidate_decl_ref = true, | 3764 | .invalidate_decl_ref = true, |
| 3820 | }; | 3765 | }; |
| 3821 | 3766 | ||
| 3822 | const has_runtime_bits = queue_linker_work and (is_func or try sema.typeHasRuntimeBits(decl.ty)); | 3767 | const has_runtime_bits = queue_linker_work and (is_func or try sema.typeHasRuntimeBits(decl_ty)); |
| 3823 | if (has_runtime_bits) { | 3768 | if (has_runtime_bits) { |
| 3824 | // Needed for codegen_decl which will call updateDecl and then the | 3769 | // Needed for codegen_decl which will call updateDecl and then the |
| 3825 | // codegen backend wants full access to the Decl Type. | 3770 | // codegen backend wants full access to the Decl Type. |
| 3826 | try sema.resolveTypeFully(decl.ty); | 3771 | try sema.resolveTypeFully(decl_ty); |
| 3827 | 3772 | ||
| 3828 | try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index }); | 3773 | try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index }); |
| 3829 | 3774 | ||
| ... | @@ -3850,7 +3795,7 @@ fn semaAnonOwnerDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult { | ... | @@ -3850,7 +3795,7 @@ fn semaAnonOwnerDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult { |
| 3850 | 3795 | ||
| 3851 | log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)}); | 3796 | log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)}); |
| 3852 | 3797 | ||
| 3853 | switch (decl.ty.zigTypeTag(zcu)) { | 3798 | switch (decl.typeOf(zcu).zigTypeTag(zcu)) { |
| 3854 | .Fn => @panic("TODO: update fn instance"), | 3799 | .Fn => @panic("TODO: update fn instance"), |
| 3855 | .Type => {}, | 3800 | .Type => {}, |
| 3856 | else => unreachable, | 3801 | else => unreachable, |
| ... | @@ -4380,7 +4325,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void | ... | @@ -4380,7 +4325,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void |
| 4380 | const decl = zcu.declPtr(decl_index); | 4325 | const decl = zcu.declPtr(decl_index); |
| 4381 | const was_exported = decl.is_exported; | 4326 | const was_exported = decl.is_exported; |
| 4382 | assert(decl.kind == kind); // ZIR tracking should preserve this | 4327 | assert(decl.kind == kind); // ZIR tracking should preserve this |
| 4383 | assert(decl.alive); | ||
| 4384 | decl.name = decl_name; | 4328 | decl.name = decl_name; |
| 4385 | decl.src_node = decl_node; | 4329 | decl.src_node = decl_node; |
| 4386 | decl.src_line = line; | 4330 | decl.src_line = line; |
| ... | @@ -4397,7 +4341,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void | ... | @@ -4397,7 +4341,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void |
| 4397 | new_decl.is_pub = declaration.flags.is_pub; | 4341 | new_decl.is_pub = declaration.flags.is_pub; |
| 4398 | new_decl.is_exported = declaration.flags.is_export; | 4342 | new_decl.is_exported = declaration.flags.is_export; |
| 4399 | new_decl.zir_decl_index = tracked_inst.toOptional(); | 4343 | new_decl.zir_decl_index = tracked_inst.toOptional(); |
| 4400 | new_decl.alive = true; // This Decl corresponds to an AST node and is therefore always alive. | ||
| 4401 | break :decl_index .{ false, new_decl_index }; | 4344 | break :decl_index .{ false, new_decl_index }; |
| 4402 | }; | 4345 | }; |
| 4403 | 4346 | ||
| ... | @@ -4450,22 +4393,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void | ... | @@ -4450,22 +4393,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void |
| 4450 | } | 4393 | } |
| 4451 | } | 4394 | } |
| 4452 | 4395 | ||
| 4453 | /// This function is exclusively called for anonymous decls. | ||
| 4454 | /// All resources referenced by anonymous decls are owned by InternPool | ||
| 4455 | /// so there is no cleanup to do here. | ||
| 4456 | pub fn deleteUnusedDecl(mod: *Module, decl_index: Decl.Index) void { | ||
| 4457 | const gpa = mod.gpa; | ||
| 4458 | const ip = &mod.intern_pool; | ||
| 4459 | |||
| 4460 | ip.destroyDecl(gpa, decl_index); | ||
| 4461 | |||
| 4462 | if (mod.emit_h) |mod_emit_h| { | ||
| 4463 | const decl_emit_h = mod_emit_h.declPtr(decl_index); | ||
| 4464 | decl_emit_h.fwd_decl.deinit(gpa); | ||
| 4465 | decl_emit_h.* = undefined; | ||
| 4466 | } | ||
| 4467 | } | ||
| 4468 | |||
| 4469 | /// Cancel the creation of an anon decl and delete any references to it. | 4396 | /// Cancel the creation of an anon decl and delete any references to it. |
| 4470 | /// If other decls depend on this decl, they must be aborted first. | 4397 | /// If other decls depend on this decl, they must be aborted first. |
| 4471 | pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void { | 4398 | pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void { |
| ... | @@ -4475,12 +4402,8 @@ pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void { | ... | @@ -4475,12 +4402,8 @@ pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void { |
| 4475 | 4402 | ||
| 4476 | /// Finalize the creation of an anon decl. | 4403 | /// Finalize the creation of an anon decl. |
| 4477 | pub fn finalizeAnonDecl(mod: *Module, decl_index: Decl.Index) Allocator.Error!void { | 4404 | pub fn finalizeAnonDecl(mod: *Module, decl_index: Decl.Index) Allocator.Error!void { |
| 4478 | // The Decl starts off with alive=false and the codegen backend will set alive=true | 4405 | if (mod.declPtr(decl_index).typeOf(mod).isFnOrHasRuntimeBits(mod)) { |
| 4479 | // if the Decl is referenced by an instruction or another constant. Otherwise, | 4406 | try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index }); |
| 4480 | // the Decl will be garbage collected by the `codegen_decl` task instead of sent | ||
| 4481 | // to the linker. | ||
| 4482 | if (mod.declPtr(decl_index).ty.isFnOrHasRuntimeBits(mod)) { | ||
| 4483 | try mod.comp.anon_work_queue.writeItem(.{ .codegen_decl = decl_index }); | ||
| 4484 | } | 4407 | } |
| 4485 | } | 4408 | } |
| 4486 | 4409 | ||
| ... | @@ -4563,7 +4486,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato | ... | @@ -4563,7 +4486,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato |
| 4563 | // the runtime-known parameters only, not to be confused with the | 4486 | // the runtime-known parameters only, not to be confused with the |
| 4564 | // generic_owner function type, which potentially has more parameters, | 4487 | // generic_owner function type, which potentially has more parameters, |
| 4565 | // including comptime parameters. | 4488 | // including comptime parameters. |
| 4566 | const fn_ty = decl.ty; | 4489 | const fn_ty = decl.typeOf(mod); |
| 4567 | const fn_ty_info = mod.typeToFunc(fn_ty).?; | 4490 | const fn_ty_info = mod.typeToFunc(fn_ty).?; |
| 4568 | 4491 | ||
| 4569 | var sema: Sema = .{ | 4492 | var sema: Sema = .{ |
| ... | @@ -4812,7 +4735,6 @@ pub fn allocateNewDecl( | ... | @@ -4812,7 +4735,6 @@ pub fn allocateNewDecl( |
| 4812 | .src_line = undefined, | 4735 | .src_line = undefined, |
| 4813 | .has_tv = false, | 4736 | .has_tv = false, |
| 4814 | .owns_tv = false, | 4737 | .owns_tv = false, |
| 4815 | .ty = undefined, | ||
| 4816 | .val = undefined, | 4738 | .val = undefined, |
| 4817 | .alignment = undefined, | 4739 | .alignment = undefined, |
| 4818 | .@"linksection" = .none, | 4740 | .@"linksection" = .none, |
| ... | @@ -4821,7 +4743,6 @@ pub fn allocateNewDecl( | ... | @@ -4821,7 +4743,6 @@ pub fn allocateNewDecl( |
| 4821 | .zir_decl_index = .none, | 4743 | .zir_decl_index = .none, |
| 4822 | .is_pub = false, | 4744 | .is_pub = false, |
| 4823 | .is_exported = false, | 4745 | .is_exported = false, |
| 4824 | .alive = false, | ||
| 4825 | .kind = .anon, | 4746 | .kind = .anon, |
| 4826 | }); | 4747 | }); |
| 4827 | 4748 | ||
| ... | @@ -4856,41 +4777,18 @@ pub fn errorSetBits(mod: *Module) u16 { | ... | @@ -4856,41 +4777,18 @@ pub fn errorSetBits(mod: *Module) u16 { |
| 4856 | return std.math.log2_int_ceil(ErrorInt, mod.error_limit + 1); // +1 for no error | 4777 | return std.math.log2_int_ceil(ErrorInt, mod.error_limit + 1); // +1 for no error |
| 4857 | } | 4778 | } |
| 4858 | 4779 | ||
| 4859 | pub fn createAnonymousDecl(mod: *Module, block: *Sema.Block, typed_value: TypedValue) !Decl.Index { | ||
| 4860 | const src_decl = mod.declPtr(block.src_decl); | ||
| 4861 | return mod.createAnonymousDeclFromDecl(src_decl, block.namespace, typed_value); | ||
| 4862 | } | ||
| 4863 | |||
| 4864 | pub fn createAnonymousDeclFromDecl( | ||
| 4865 | mod: *Module, | ||
| 4866 | src_decl: *Decl, | ||
| 4867 | namespace: Namespace.Index, | ||
| 4868 | tv: TypedValue, | ||
| 4869 | ) !Decl.Index { | ||
| 4870 | const new_decl_index = try mod.allocateNewDecl(namespace, src_decl.src_node); | ||
| 4871 | errdefer mod.destroyDecl(new_decl_index); | ||
| 4872 | const name = try mod.intern_pool.getOrPutStringFmt(mod.gpa, "{}__anon_{d}", .{ | ||
| 4873 | src_decl.name.fmt(&mod.intern_pool), @intFromEnum(new_decl_index), | ||
| 4874 | }); | ||
| 4875 | try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, tv, name); | ||
| 4876 | return new_decl_index; | ||
| 4877 | } | ||
| 4878 | |||
| 4879 | pub fn initNewAnonDecl( | 4780 | pub fn initNewAnonDecl( |
| 4880 | mod: *Module, | 4781 | mod: *Module, |
| 4881 | new_decl_index: Decl.Index, | 4782 | new_decl_index: Decl.Index, |
| 4882 | src_line: u32, | 4783 | src_line: u32, |
| 4883 | typed_value: TypedValue, | 4784 | val: Value, |
| 4884 | name: InternPool.NullTerminatedString, | 4785 | name: InternPool.NullTerminatedString, |
| 4885 | ) Allocator.Error!void { | 4786 | ) Allocator.Error!void { |
| 4886 | assert(typed_value.ty.toIntern() == mod.intern_pool.typeOf(typed_value.val.toIntern())); | ||
| 4887 | |||
| 4888 | const new_decl = mod.declPtr(new_decl_index); | 4787 | const new_decl = mod.declPtr(new_decl_index); |
| 4889 | 4788 | ||
| 4890 | new_decl.name = name; | 4789 | new_decl.name = name; |
| 4891 | new_decl.src_line = src_line; | 4790 | new_decl.src_line = src_line; |
| 4892 | new_decl.ty = typed_value.ty; | 4791 | new_decl.val = val; |
| 4893 | new_decl.val = typed_value.val; | ||
| 4894 | new_decl.alignment = .none; | 4792 | new_decl.alignment = .none; |
| 4895 | new_decl.@"linksection" = .none; | 4793 | new_decl.@"linksection" = .none; |
| 4896 | new_decl.has_tv = true; | 4794 | new_decl.has_tv = true; |
| ... | @@ -5419,9 +5317,9 @@ pub fn populateTestFunctions( | ... | @@ -5419,9 +5317,9 @@ pub fn populateTestFunctions( |
| 5419 | try mod.ensureDeclAnalyzed(decl_index); | 5317 | try mod.ensureDeclAnalyzed(decl_index); |
| 5420 | } | 5318 | } |
| 5421 | const decl = mod.declPtr(decl_index); | 5319 | const decl = mod.declPtr(decl_index); |
| 5422 | const test_fn_ty = decl.ty.slicePtrFieldType(mod).childType(mod); | 5320 | const test_fn_ty = decl.typeOf(mod).slicePtrFieldType(mod).childType(mod); |
| 5423 | 5321 | ||
| 5424 | const array_decl_index = d: { | 5322 | const array_anon_decl: InternPool.Key.Ptr.Addr.AnonDecl = array: { |
| 5425 | // Add mod.test_functions to an array decl then make the test_functions | 5323 | // Add mod.test_functions to an array decl then make the test_functions |
| 5426 | // decl reference it as a slice. | 5324 | // decl reference it as a slice. |
| 5427 | const test_fn_vals = try gpa.alloc(InternPool.Index, mod.test_functions.count()); | 5325 | const test_fn_vals = try gpa.alloc(InternPool.Index, mod.test_functions.count()); |
| ... | @@ -5431,21 +5329,20 @@ pub fn populateTestFunctions( | ... | @@ -5431,21 +5329,20 @@ pub fn populateTestFunctions( |
| 5431 | const test_decl = mod.declPtr(test_decl_index); | 5329 | const test_decl = mod.declPtr(test_decl_index); |
| 5432 | const test_decl_name = try gpa.dupe(u8, ip.stringToSlice(try test_decl.fullyQualifiedName(mod))); | 5330 | const test_decl_name = try gpa.dupe(u8, ip.stringToSlice(try test_decl.fullyQualifiedName(mod))); |
| 5433 | defer gpa.free(test_decl_name); | 5331 | defer gpa.free(test_decl_name); |
| 5434 | const test_name_decl_index = n: { | 5332 | const test_name_anon_decl: InternPool.Key.Ptr.Addr.AnonDecl = n: { |
| 5435 | const test_name_decl_ty = try mod.arrayType(.{ | 5333 | const test_name_ty = try mod.arrayType(.{ |
| 5436 | .len = test_decl_name.len, | 5334 | .len = test_decl_name.len, |
| 5437 | .child = .u8_type, | 5335 | .child = .u8_type, |
| 5438 | }); | 5336 | }); |
| 5439 | const test_name_decl_index = try mod.createAnonymousDeclFromDecl(decl, decl.src_namespace, .{ | 5337 | const test_name_val = try mod.intern(.{ .aggregate = .{ |
| 5440 | .ty = test_name_decl_ty, | 5338 | .ty = test_name_ty.toIntern(), |
| 5441 | .val = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 5339 | .storage = .{ .bytes = test_decl_name }, |
| 5442 | .ty = test_name_decl_ty.toIntern(), | 5340 | } }); |
| 5443 | .storage = .{ .bytes = test_decl_name }, | 5341 | break :n .{ |
| 5444 | } }))), | 5342 | .orig_ty = (try mod.singleConstPtrType(test_name_ty)).toIntern(), |
| 5445 | }); | 5343 | .val = test_name_val, |
| 5446 | break :n test_name_decl_index; | 5344 | }; |
| 5447 | }; | 5345 | }; |
| 5448 | try mod.linkerUpdateDecl(test_name_decl_index); | ||
| 5449 | 5346 | ||
| 5450 | const test_fn_fields = .{ | 5347 | const test_fn_fields = .{ |
| 5451 | // name | 5348 | // name |
| ... | @@ -5453,7 +5350,7 @@ pub fn populateTestFunctions( | ... | @@ -5453,7 +5350,7 @@ pub fn populateTestFunctions( |
| 5453 | .ty = .slice_const_u8_type, | 5350 | .ty = .slice_const_u8_type, |
| 5454 | .ptr = try mod.intern(.{ .ptr = .{ | 5351 | .ptr = try mod.intern(.{ .ptr = .{ |
| 5455 | .ty = .manyptr_const_u8_type, | 5352 | .ty = .manyptr_const_u8_type, |
| 5456 | .addr = .{ .decl = test_name_decl_index }, | 5353 | .addr = .{ .anon_decl = test_name_anon_decl }, |
| 5457 | } }), | 5354 | } }), |
| 5458 | .len = try mod.intern(.{ .int = .{ | 5355 | .len = try mod.intern(.{ .int = .{ |
| 5459 | .ty = .usize_type, | 5356 | .ty = .usize_type, |
| ... | @@ -5463,7 +5360,7 @@ pub fn populateTestFunctions( | ... | @@ -5463,7 +5360,7 @@ pub fn populateTestFunctions( |
| 5463 | // func | 5360 | // func |
| 5464 | try mod.intern(.{ .ptr = .{ | 5361 | try mod.intern(.{ .ptr = .{ |
| 5465 | .ty = try mod.intern(.{ .ptr_type = .{ | 5362 | .ty = try mod.intern(.{ .ptr_type = .{ |
| 5466 | .child = test_decl.ty.toIntern(), | 5363 | .child = test_decl.typeOf(mod).toIntern(), |
| 5467 | .flags = .{ | 5364 | .flags = .{ |
| 5468 | .is_const = true, | 5365 | .is_const = true, |
| 5469 | }, | 5366 | }, |
| ... | @@ -5477,22 +5374,20 @@ pub fn populateTestFunctions( | ... | @@ -5477,22 +5374,20 @@ pub fn populateTestFunctions( |
| 5477 | } }); | 5374 | } }); |
| 5478 | } | 5375 | } |
| 5479 | 5376 | ||
| 5480 | const array_decl_ty = try mod.arrayType(.{ | 5377 | const array_ty = try mod.arrayType(.{ |
| 5481 | .len = test_fn_vals.len, | 5378 | .len = test_fn_vals.len, |
| 5482 | .child = test_fn_ty.toIntern(), | 5379 | .child = test_fn_ty.toIntern(), |
| 5483 | .sentinel = .none, | 5380 | .sentinel = .none, |
| 5484 | }); | 5381 | }); |
| 5485 | const array_decl_index = try mod.createAnonymousDeclFromDecl(decl, decl.src_namespace, .{ | 5382 | const array_val = try mod.intern(.{ .aggregate = .{ |
| 5486 | .ty = array_decl_ty, | 5383 | .ty = array_ty.toIntern(), |
| 5487 | .val = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 5384 | .storage = .{ .elems = test_fn_vals }, |
| 5488 | .ty = array_decl_ty.toIntern(), | 5385 | } }); |
| 5489 | .storage = .{ .elems = test_fn_vals }, | 5386 | break :array .{ |
| 5490 | } }))), | 5387 | .orig_ty = (try mod.singleConstPtrType(array_ty)).toIntern(), |
| 5491 | }); | 5388 | .val = array_val, |
| 5492 | 5389 | }; | |
| 5493 | break :d array_decl_index; | ||
| 5494 | }; | 5390 | }; |
| 5495 | try mod.linkerUpdateDecl(array_decl_index); | ||
| 5496 | 5391 | ||
| 5497 | { | 5392 | { |
| 5498 | const new_ty = try mod.ptrType(.{ | 5393 | const new_ty = try mod.ptrType(.{ |
| ... | @@ -5507,7 +5402,7 @@ pub fn populateTestFunctions( | ... | @@ -5507,7 +5402,7 @@ pub fn populateTestFunctions( |
| 5507 | .ty = new_ty.toIntern(), | 5402 | .ty = new_ty.toIntern(), |
| 5508 | .ptr = try mod.intern(.{ .ptr = .{ | 5403 | .ptr = try mod.intern(.{ .ptr = .{ |
| 5509 | .ty = new_ty.slicePtrFieldType(mod).toIntern(), | 5404 | .ty = new_ty.slicePtrFieldType(mod).toIntern(), |
| 5510 | .addr = .{ .decl = array_decl_index }, | 5405 | .addr = .{ .anon_decl = array_anon_decl }, |
| 5511 | } }), | 5406 | } }), |
| 5512 | .len = (try mod.intValue(Type.usize, mod.test_functions.count())).toIntern(), | 5407 | .len = (try mod.intValue(Type.usize, mod.test_functions.count())).toIntern(), |
| 5513 | } }); | 5408 | } }); |
| ... | @@ -5515,7 +5410,6 @@ pub fn populateTestFunctions( | ... | @@ -5515,7 +5410,6 @@ pub fn populateTestFunctions( |
| 5515 | 5410 | ||
| 5516 | // Since we are replacing the Decl's value we must perform cleanup on the | 5411 | // Since we are replacing the Decl's value we must perform cleanup on the |
| 5517 | // previous value. | 5412 | // previous value. |
| 5518 | decl.ty = new_ty; | ||
| 5519 | decl.val = new_val; | 5413 | decl.val = new_val; |
| 5520 | decl.has_tv = true; | 5414 | decl.has_tv = true; |
| 5521 | } | 5415 | } |
| ... | @@ -5590,53 +5484,6 @@ fn reportRetryableFileError( | ... | @@ -5590,53 +5484,6 @@ fn reportRetryableFileError( |
| 5590 | gop.value_ptr.* = err_msg; | 5484 | gop.value_ptr.* = err_msg; |
| 5591 | } | 5485 | } |
| 5592 | 5486 | ||
| 5593 | pub fn markReferencedDeclsAlive(mod: *Module, val: Value) Allocator.Error!void { | ||
| 5594 | switch (mod.intern_pool.indexToKey(val.toIntern())) { | ||
| 5595 | .variable => |variable| try mod.markDeclIndexAlive(variable.decl), | ||
| 5596 | .extern_func => |extern_func| try mod.markDeclIndexAlive(extern_func.decl), | ||
| 5597 | .func => |func| try mod.markDeclIndexAlive(func.owner_decl), | ||
| 5598 | .error_union => |error_union| switch (error_union.val) { | ||
| 5599 | .err_name => {}, | ||
| 5600 | .payload => |payload| try mod.markReferencedDeclsAlive(Value.fromInterned(payload)), | ||
| 5601 | }, | ||
| 5602 | .slice => |slice| { | ||
| 5603 | try mod.markReferencedDeclsAlive(Value.fromInterned(slice.ptr)); | ||
| 5604 | try mod.markReferencedDeclsAlive(Value.fromInterned(slice.len)); | ||
| 5605 | }, | ||
| 5606 | .ptr => |ptr| switch (ptr.addr) { | ||
| 5607 | .decl => |decl| try mod.markDeclIndexAlive(decl), | ||
| 5608 | .anon_decl => {}, | ||
| 5609 | .int, .comptime_field, .comptime_alloc => {}, | ||
| 5610 | .eu_payload, .opt_payload => |parent| try mod.markReferencedDeclsAlive(Value.fromInterned(parent)), | ||
| 5611 | .elem, .field => |base_index| try mod.markReferencedDeclsAlive(Value.fromInterned(base_index.base)), | ||
| 5612 | }, | ||
| 5613 | .opt => |opt| if (opt.val != .none) try mod.markReferencedDeclsAlive(Value.fromInterned(opt.val)), | ||
| 5614 | .aggregate => |aggregate| for (aggregate.storage.values()) |elem| | ||
| 5615 | try mod.markReferencedDeclsAlive(Value.fromInterned(elem)), | ||
| 5616 | .un => |un| { | ||
| 5617 | if (un.tag != .none) try mod.markReferencedDeclsAlive(Value.fromInterned(un.tag)); | ||
| 5618 | try mod.markReferencedDeclsAlive(Value.fromInterned(un.val)); | ||
| 5619 | }, | ||
| 5620 | else => {}, | ||
| 5621 | } | ||
| 5622 | } | ||
| 5623 | |||
| 5624 | pub fn markDeclAlive(mod: *Module, decl: *Decl) Allocator.Error!void { | ||
| 5625 | if (decl.alive) return; | ||
| 5626 | decl.alive = true; | ||
| 5627 | |||
| 5628 | _ = try decl.internValue(mod); | ||
| 5629 | |||
| 5630 | // This is the first time we are marking this Decl alive. We must | ||
| 5631 | // therefore recurse into its value and mark any Decl it references | ||
| 5632 | // as also alive, so that any Decl referenced does not get garbage collected. | ||
| 5633 | try mod.markReferencedDeclsAlive(decl.val); | ||
| 5634 | } | ||
| 5635 | |||
| 5636 | fn markDeclIndexAlive(mod: *Module, decl_index: Decl.Index) Allocator.Error!void { | ||
| 5637 | return mod.markDeclAlive(mod.declPtr(decl_index)); | ||
| 5638 | } | ||
| 5639 | |||
| 5640 | pub fn addGlobalAssembly(mod: *Module, decl_index: Decl.Index, source: []const u8) !void { | 5487 | pub fn addGlobalAssembly(mod: *Module, decl_index: Decl.Index, source: []const u8) !void { |
| 5641 | const gop = try mod.global_assembly.getOrPut(mod.gpa, decl_index); | 5488 | const gop = try mod.global_assembly.getOrPut(mod.gpa, decl_index); |
| 5642 | if (gop.found_existing) { | 5489 | if (gop.found_existing) { |
src/Sema.zig+559-754| ... | @@ -139,8 +139,7 @@ const MaybeComptimeAlloc = struct { | ... | @@ -139,8 +139,7 @@ const MaybeComptimeAlloc = struct { |
| 139 | }; | 139 | }; |
| 140 | 140 | ||
| 141 | const ComptimeAlloc = struct { | 141 | const ComptimeAlloc = struct { |
| 142 | ty: Type, | 142 | val: MutableValue, |
| 143 | val: Value, | ||
| 144 | is_const: bool, | 143 | is_const: bool, |
| 145 | /// `.none` indicates that the alignment is the natural alignment of `val`. | 144 | /// `.none` indicates that the alignment is the natural alignment of `val`. |
| 146 | alignment: Alignment, | 145 | alignment: Alignment, |
| ... | @@ -153,8 +152,7 @@ const ComptimeAlloc = struct { | ... | @@ -153,8 +152,7 @@ const ComptimeAlloc = struct { |
| 153 | fn newComptimeAlloc(sema: *Sema, block: *Block, ty: Type, alignment: Alignment) !ComptimeAllocIndex { | 152 | fn newComptimeAlloc(sema: *Sema, block: *Block, ty: Type, alignment: Alignment) !ComptimeAllocIndex { |
| 154 | const idx = sema.comptime_allocs.items.len; | 153 | const idx = sema.comptime_allocs.items.len; |
| 155 | try sema.comptime_allocs.append(sema.gpa, .{ | 154 | try sema.comptime_allocs.append(sema.gpa, .{ |
| 156 | .ty = ty, | 155 | .val = .{ .interned = try sema.mod.intern(.{ .undef = ty.toIntern() }) }, |
| 157 | .val = Value.fromInterned(try sema.mod.intern(.{ .undef = ty.toIntern() })), | ||
| 158 | .is_const = false, | 156 | .is_const = false, |
| 159 | .alignment = alignment, | 157 | .alignment = alignment, |
| 160 | .runtime_index = block.runtime_index, | 158 | .runtime_index = block.runtime_index, |
| ... | @@ -175,8 +173,8 @@ const log = std.log.scoped(.sema); | ... | @@ -175,8 +173,8 @@ const log = std.log.scoped(.sema); |
| 175 | 173 | ||
| 176 | const Sema = @This(); | 174 | const Sema = @This(); |
| 177 | const Value = @import("Value.zig"); | 175 | const Value = @import("Value.zig"); |
| 176 | const MutableValue = @import("mutable_value.zig").MutableValue; | ||
| 178 | const Type = @import("type.zig").Type; | 177 | const Type = @import("type.zig").Type; |
| 179 | const TypedValue = @import("TypedValue.zig"); | ||
| 180 | const Air = @import("Air.zig"); | 178 | const Air = @import("Air.zig"); |
| 181 | const Zir = std.zig.Zir; | 179 | const Zir = std.zig.Zir; |
| 182 | const Module = @import("Module.zig"); | 180 | const Module = @import("Module.zig"); |
| ... | @@ -1709,7 +1707,7 @@ fn analyzeBodyInner( | ... | @@ -1709,7 +1707,7 @@ fn analyzeBodyInner( |
| 1709 | .needed_comptime_reason = "condition in comptime branch must be comptime-known", | 1707 | .needed_comptime_reason = "condition in comptime branch must be comptime-known", |
| 1710 | .block_comptime_reason = block.comptime_reason, | 1708 | .block_comptime_reason = block.comptime_reason, |
| 1711 | }); | 1709 | }); |
| 1712 | const inline_body = if (cond.val.toBool()) then_body else else_body; | 1710 | const inline_body = if (cond.toBool()) then_body else else_body; |
| 1713 | 1711 | ||
| 1714 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); | 1712 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); |
| 1715 | 1713 | ||
| ... | @@ -1729,7 +1727,7 @@ fn analyzeBodyInner( | ... | @@ -1729,7 +1727,7 @@ fn analyzeBodyInner( |
| 1729 | .needed_comptime_reason = "condition in comptime branch must be comptime-known", | 1727 | .needed_comptime_reason = "condition in comptime branch must be comptime-known", |
| 1730 | .block_comptime_reason = block.comptime_reason, | 1728 | .block_comptime_reason = block.comptime_reason, |
| 1731 | }); | 1729 | }); |
| 1732 | const inline_body = if (cond.val.toBool()) then_body else else_body; | 1730 | const inline_body = if (cond.toBool()) then_body else else_body; |
| 1733 | 1731 | ||
| 1734 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); | 1732 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); |
| 1735 | const old_runtime_index = block.runtime_index; | 1733 | const old_runtime_index = block.runtime_index; |
| ... | @@ -1882,10 +1880,10 @@ pub fn toConstString( | ... | @@ -1882,10 +1880,10 @@ pub fn toConstString( |
| 1882 | air_inst: Air.Inst.Ref, | 1880 | air_inst: Air.Inst.Ref, |
| 1883 | reason: NeededComptimeReason, | 1881 | reason: NeededComptimeReason, |
| 1884 | ) ![]u8 { | 1882 | ) ![]u8 { |
| 1885 | const wanted_type = Type.slice_const_u8; | 1883 | const coerced_inst = try sema.coerce(block, Type.slice_const_u8, air_inst, src); |
| 1886 | const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); | 1884 | const slice_val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason); |
| 1887 | const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason); | 1885 | const arr_val = try sema.derefSliceAsArray(block, src, slice_val, reason); |
| 1888 | return val.toAllocatedBytes(wanted_type, sema.arena, sema.mod); | 1886 | return arr_val.toAllocatedBytes(arr_val.typeOf(sema.mod), sema.arena, sema.mod); |
| 1889 | } | 1887 | } |
| 1890 | 1888 | ||
| 1891 | pub fn resolveConstStringIntern( | 1889 | pub fn resolveConstStringIntern( |
| ... | @@ -2180,13 +2178,9 @@ fn resolveInstConst( | ... | @@ -2180,13 +2178,9 @@ fn resolveInstConst( |
| 2180 | src: LazySrcLoc, | 2178 | src: LazySrcLoc, |
| 2181 | zir_ref: Zir.Inst.Ref, | 2179 | zir_ref: Zir.Inst.Ref, |
| 2182 | reason: NeededComptimeReason, | 2180 | reason: NeededComptimeReason, |
| 2183 | ) CompileError!TypedValue { | 2181 | ) CompileError!Value { |
| 2184 | const air_ref = try sema.resolveInst(zir_ref); | 2182 | const air_ref = try sema.resolveInst(zir_ref); |
| 2185 | const val = try sema.resolveConstDefinedValue(block, src, air_ref, reason); | 2183 | return sema.resolveConstDefinedValue(block, src, air_ref, reason); |
| 2186 | return .{ | ||
| 2187 | .ty = sema.typeOf(air_ref), | ||
| 2188 | .val = val, | ||
| 2189 | }; | ||
| 2190 | } | 2184 | } |
| 2191 | 2185 | ||
| 2192 | /// Value Tag may be `undef` or `variable`. | 2186 | /// Value Tag may be `undef` or `variable`. |
| ... | @@ -2195,7 +2189,7 @@ pub fn resolveFinalDeclValue( | ... | @@ -2195,7 +2189,7 @@ pub fn resolveFinalDeclValue( |
| 2195 | block: *Block, | 2189 | block: *Block, |
| 2196 | src: LazySrcLoc, | 2190 | src: LazySrcLoc, |
| 2197 | air_ref: Air.Inst.Ref, | 2191 | air_ref: Air.Inst.Ref, |
| 2198 | ) CompileError!TypedValue { | 2192 | ) CompileError!Value { |
| 2199 | const val = try sema.resolveValueAllowVariables(air_ref) orelse { | 2193 | const val = try sema.resolveValueAllowVariables(air_ref) orelse { |
| 2200 | return sema.failWithNeededComptime(block, src, .{ | 2194 | return sema.failWithNeededComptime(block, src, .{ |
| 2201 | .needed_comptime_reason = "global variable initializer must be comptime-known", | 2195 | .needed_comptime_reason = "global variable initializer must be comptime-known", |
| ... | @@ -2205,10 +2199,7 @@ pub fn resolveFinalDeclValue( | ... | @@ -2205,10 +2199,7 @@ pub fn resolveFinalDeclValue( |
| 2205 | if (val.canMutateComptimeVarState(sema.mod)) { | 2199 | if (val.canMutateComptimeVarState(sema.mod)) { |
| 2206 | return sema.fail(block, src, "global variable contains reference to comptime var", .{}); | 2200 | return sema.fail(block, src, "global variable contains reference to comptime var", .{}); |
| 2207 | } | 2201 | } |
| 2208 | return .{ | 2202 | return val; |
| 2209 | .ty = sema.typeOf(air_ref), | ||
| 2210 | .val = val, | ||
| 2211 | }; | ||
| 2212 | } | 2203 | } |
| 2213 | 2204 | ||
| 2214 | fn failWithNeededComptime(sema: *Sema, block: *Block, src: LazySrcLoc, reason: NeededComptimeReason) CompileError { | 2205 | fn failWithNeededComptime(sema: *Sema, block: *Block, src: LazySrcLoc, reason: NeededComptimeReason) CompileError { |
| ... | @@ -2281,7 +2272,7 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: | ... | @@ -2281,7 +2272,7 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: |
| 2281 | if (int_ty.zigTypeTag(mod) == .Vector) { | 2272 | if (int_ty.zigTypeTag(mod) == .Vector) { |
| 2282 | const msg = msg: { | 2273 | const msg = msg: { |
| 2283 | const msg = try sema.errMsg(block, src, "overflow of vector type '{}' with value '{}'", .{ | 2274 | const msg = try sema.errMsg(block, src, "overflow of vector type '{}' with value '{}'", .{ |
| 2284 | int_ty.fmt(sema.mod), val.fmtValue(int_ty, sema.mod), | 2275 | int_ty.fmt(sema.mod), val.fmtValue(sema.mod), |
| 2285 | }); | 2276 | }); |
| 2286 | errdefer msg.destroy(sema.gpa); | 2277 | errdefer msg.destroy(sema.gpa); |
| 2287 | try sema.errNote(block, src, msg, "when computing vector element at index '{d}'", .{vector_index}); | 2278 | try sema.errNote(block, src, msg, "when computing vector element at index '{d}'", .{vector_index}); |
| ... | @@ -2290,7 +2281,7 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: | ... | @@ -2290,7 +2281,7 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: |
| 2290 | return sema.failWithOwnedErrorMsg(block, msg); | 2281 | return sema.failWithOwnedErrorMsg(block, msg); |
| 2291 | } | 2282 | } |
| 2292 | return sema.fail(block, src, "overflow of integer type '{}' with value '{}'", .{ | 2283 | return sema.fail(block, src, "overflow of integer type '{}' with value '{}'", .{ |
| 2293 | int_ty.fmt(sema.mod), val.fmtValue(int_ty, sema.mod), | 2284 | int_ty.fmt(sema.mod), val.fmtValue(sema.mod), |
| 2294 | }); | 2285 | }); |
| 2295 | } | 2286 | } |
| 2296 | 2287 | ||
| ... | @@ -2826,10 +2817,14 @@ fn zirStructDecl( | ... | @@ -2826,10 +2817,14 @@ fn zirStructDecl( |
| 2826 | }); | 2817 | }); |
| 2827 | errdefer wip_ty.cancel(ip); | 2818 | errdefer wip_ty.cancel(ip); |
| 2828 | 2819 | ||
| 2829 | const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{ | 2820 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( |
| 2830 | .ty = Type.type, | 2821 | block, |
| 2831 | .val = Value.fromInterned(wip_ty.index), | 2822 | src, |
| 2832 | }, small.name_strategy, "struct", inst); | 2823 | Value.fromInterned(wip_ty.index), |
| 2824 | small.name_strategy, | ||
| 2825 | "struct", | ||
| 2826 | inst, | ||
| 2827 | ); | ||
| 2833 | mod.declPtr(new_decl_index).owns_tv = true; | 2828 | mod.declPtr(new_decl_index).owns_tv = true; |
| 2834 | errdefer mod.abortAnonDecl(new_decl_index); | 2829 | errdefer mod.abortAnonDecl(new_decl_index); |
| 2835 | 2830 | ||
| ... | @@ -2862,7 +2857,7 @@ fn createAnonymousDeclTypeNamed( | ... | @@ -2862,7 +2857,7 @@ fn createAnonymousDeclTypeNamed( |
| 2862 | sema: *Sema, | 2857 | sema: *Sema, |
| 2863 | block: *Block, | 2858 | block: *Block, |
| 2864 | src: LazySrcLoc, | 2859 | src: LazySrcLoc, |
| 2865 | typed_value: TypedValue, | 2860 | val: Value, |
| 2866 | name_strategy: Zir.Inst.NameStrategy, | 2861 | name_strategy: Zir.Inst.NameStrategy, |
| 2867 | anon_prefix: []const u8, | 2862 | anon_prefix: []const u8, |
| 2868 | inst: ?Zir.Inst.Index, | 2863 | inst: ?Zir.Inst.Index, |
| ... | @@ -2888,12 +2883,12 @@ fn createAnonymousDeclTypeNamed( | ... | @@ -2888,12 +2883,12 @@ fn createAnonymousDeclTypeNamed( |
| 2888 | const name = mod.intern_pool.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{ | 2883 | const name = mod.intern_pool.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{ |
| 2889 | src_decl.name.fmt(&mod.intern_pool), anon_prefix, @intFromEnum(new_decl_index), | 2884 | src_decl.name.fmt(&mod.intern_pool), anon_prefix, @intFromEnum(new_decl_index), |
| 2890 | }) catch unreachable; | 2885 | }) catch unreachable; |
| 2891 | try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, typed_value, name); | 2886 | try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name); |
| 2892 | return new_decl_index; | 2887 | return new_decl_index; |
| 2893 | }, | 2888 | }, |
| 2894 | .parent => { | 2889 | .parent => { |
| 2895 | const name = mod.declPtr(block.src_decl).name; | 2890 | const name = mod.declPtr(block.src_decl).name; |
| 2896 | try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, typed_value, name); | 2891 | try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name); |
| 2897 | return new_decl_index; | 2892 | return new_decl_index; |
| 2898 | }, | 2893 | }, |
| 2899 | .func => { | 2894 | .func => { |
| ... | @@ -2916,10 +2911,10 @@ fn createAnonymousDeclTypeNamed( | ... | @@ -2916,10 +2911,10 @@ fn createAnonymousDeclTypeNamed( |
| 2916 | // function and the name doesn't matter since it will later | 2911 | // function and the name doesn't matter since it will later |
| 2917 | // result in a compile error. | 2912 | // result in a compile error. |
| 2918 | const arg_val = sema.resolveConstValue(block, .unneeded, arg, undefined) catch | 2913 | const arg_val = sema.resolveConstValue(block, .unneeded, arg, undefined) catch |
| 2919 | return sema.createAnonymousDeclTypeNamed(block, src, typed_value, .anon, anon_prefix, null); | 2914 | return sema.createAnonymousDeclTypeNamed(block, src, val, .anon, anon_prefix, null); |
| 2920 | 2915 | ||
| 2921 | if (arg_i != 0) try writer.writeByte(','); | 2916 | if (arg_i != 0) try writer.writeByte(','); |
| 2922 | try writer.print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)}); | 2917 | try writer.print("{}", .{arg_val.fmtValue(sema.mod)}); |
| 2923 | 2918 | ||
| 2924 | arg_i += 1; | 2919 | arg_i += 1; |
| 2925 | continue; | 2920 | continue; |
| ... | @@ -2929,7 +2924,7 @@ fn createAnonymousDeclTypeNamed( | ... | @@ -2929,7 +2924,7 @@ fn createAnonymousDeclTypeNamed( |
| 2929 | 2924 | ||
| 2930 | try writer.writeByte(')'); | 2925 | try writer.writeByte(')'); |
| 2931 | const name = try mod.intern_pool.getOrPutString(gpa, buf.items); | 2926 | const name = try mod.intern_pool.getOrPutString(gpa, buf.items); |
| 2932 | try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, typed_value, name); | 2927 | try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name); |
| 2933 | return new_decl_index; | 2928 | return new_decl_index; |
| 2934 | }, | 2929 | }, |
| 2935 | .dbg_var => { | 2930 | .dbg_var => { |
| ... | @@ -2944,12 +2939,12 @@ fn createAnonymousDeclTypeNamed( | ... | @@ -2944,12 +2939,12 @@ fn createAnonymousDeclTypeNamed( |
| 2944 | src_decl.name.fmt(&mod.intern_pool), zir_data[i].str_op.getStr(sema.code), | 2939 | src_decl.name.fmt(&mod.intern_pool), zir_data[i].str_op.getStr(sema.code), |
| 2945 | }); | 2940 | }); |
| 2946 | 2941 | ||
| 2947 | try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, typed_value, name); | 2942 | try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name); |
| 2948 | return new_decl_index; | 2943 | return new_decl_index; |
| 2949 | }, | 2944 | }, |
| 2950 | else => {}, | 2945 | else => {}, |
| 2951 | }; | 2946 | }; |
| 2952 | return sema.createAnonymousDeclTypeNamed(block, src, typed_value, .anon, anon_prefix, null); | 2947 | return sema.createAnonymousDeclTypeNamed(block, src, val, .anon, anon_prefix, null); |
| 2953 | }, | 2948 | }, |
| 2954 | } | 2949 | } |
| 2955 | } | 2950 | } |
| ... | @@ -3049,10 +3044,14 @@ fn zirEnumDecl( | ... | @@ -3049,10 +3044,14 @@ fn zirEnumDecl( |
| 3049 | 3044 | ||
| 3050 | errdefer if (!done) wip_ty.cancel(ip); | 3045 | errdefer if (!done) wip_ty.cancel(ip); |
| 3051 | 3046 | ||
| 3052 | const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{ | 3047 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( |
| 3053 | .ty = Type.type, | 3048 | block, |
| 3054 | .val = Value.fromInterned(wip_ty.index), | 3049 | src, |
| 3055 | }, small.name_strategy, "enum", inst); | 3050 | Value.fromInterned(wip_ty.index), |
| 3051 | small.name_strategy, | ||
| 3052 | "enum", | ||
| 3053 | inst, | ||
| 3054 | ); | ||
| 3056 | const new_decl = mod.declPtr(new_decl_index); | 3055 | const new_decl = mod.declPtr(new_decl_index); |
| 3057 | new_decl.owns_tv = true; | 3056 | new_decl.owns_tv = true; |
| 3058 | errdefer if (!done) mod.abortAnonDecl(new_decl_index); | 3057 | errdefer if (!done) mod.abortAnonDecl(new_decl_index); |
| ... | @@ -3187,7 +3186,7 @@ fn zirEnumDecl( | ... | @@ -3187,7 +3186,7 @@ fn zirEnumDecl( |
| 3187 | }).lazy; | 3186 | }).lazy; |
| 3188 | const other_field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = conflict.prev_field_idx }).lazy; | 3187 | const other_field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = conflict.prev_field_idx }).lazy; |
| 3189 | const msg = msg: { | 3188 | const msg = msg: { |
| 3190 | const msg = try sema.errMsg(block, value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(int_tag_ty, sema.mod)}); | 3189 | const msg = try sema.errMsg(block, value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod)}); |
| 3191 | errdefer msg.destroy(gpa); | 3190 | errdefer msg.destroy(gpa); |
| 3192 | try sema.errNote(block, other_field_src, msg, "other occurrence here", .{}); | 3191 | try sema.errNote(block, other_field_src, msg, "other occurrence here", .{}); |
| 3193 | break :msg msg; | 3192 | break :msg msg; |
| ... | @@ -3207,7 +3206,7 @@ fn zirEnumDecl( | ... | @@ -3207,7 +3206,7 @@ fn zirEnumDecl( |
| 3207 | const field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = field_i }).lazy; | 3206 | const field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = field_i }).lazy; |
| 3208 | const other_field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = conflict.prev_field_idx }).lazy; | 3207 | const other_field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = conflict.prev_field_idx }).lazy; |
| 3209 | const msg = msg: { | 3208 | const msg = msg: { |
| 3210 | const msg = try sema.errMsg(block, field_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(int_tag_ty, sema.mod)}); | 3209 | const msg = try sema.errMsg(block, field_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod)}); |
| 3211 | errdefer msg.destroy(gpa); | 3210 | errdefer msg.destroy(gpa); |
| 3212 | try sema.errNote(block, other_field_src, msg, "other occurrence here", .{}); | 3211 | try sema.errNote(block, other_field_src, msg, "other occurrence here", .{}); |
| 3213 | break :msg msg; | 3212 | break :msg msg; |
| ... | @@ -3229,7 +3228,7 @@ fn zirEnumDecl( | ... | @@ -3229,7 +3228,7 @@ fn zirEnumDecl( |
| 3229 | .range = if (has_tag_value) .value else .name, | 3228 | .range = if (has_tag_value) .value else .name, |
| 3230 | }).lazy; | 3229 | }).lazy; |
| 3231 | const msg = try sema.errMsg(block, value_src, "enumeration value '{}' too large for type '{}'", .{ | 3230 | const msg = try sema.errMsg(block, value_src, "enumeration value '{}' too large for type '{}'", .{ |
| 3232 | last_tag_val.?.fmtValue(int_tag_ty, mod), int_tag_ty.fmt(mod), | 3231 | last_tag_val.?.fmtValue(mod), int_tag_ty.fmt(mod), |
| 3233 | }); | 3232 | }); |
| 3234 | return sema.failWithOwnedErrorMsg(block, msg); | 3233 | return sema.failWithOwnedErrorMsg(block, msg); |
| 3235 | } | 3234 | } |
| ... | @@ -3316,10 +3315,14 @@ fn zirUnionDecl( | ... | @@ -3316,10 +3315,14 @@ fn zirUnionDecl( |
| 3316 | }); | 3315 | }); |
| 3317 | errdefer wip_ty.cancel(ip); | 3316 | errdefer wip_ty.cancel(ip); |
| 3318 | 3317 | ||
| 3319 | const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{ | 3318 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( |
| 3320 | .ty = Type.type, | 3319 | block, |
| 3321 | .val = Value.fromInterned(wip_ty.index), | 3320 | src, |
| 3322 | }, small.name_strategy, "union", inst); | 3321 | Value.fromInterned(wip_ty.index), |
| 3322 | small.name_strategy, | ||
| 3323 | "union", | ||
| 3324 | inst, | ||
| 3325 | ); | ||
| 3323 | mod.declPtr(new_decl_index).owns_tv = true; | 3326 | mod.declPtr(new_decl_index).owns_tv = true; |
| 3324 | errdefer mod.abortAnonDecl(new_decl_index); | 3327 | errdefer mod.abortAnonDecl(new_decl_index); |
| 3325 | 3328 | ||
| ... | @@ -3400,10 +3403,14 @@ fn zirOpaqueDecl( | ... | @@ -3400,10 +3403,14 @@ fn zirOpaqueDecl( |
| 3400 | }; | 3403 | }; |
| 3401 | errdefer wip_ty.cancel(ip); | 3404 | errdefer wip_ty.cancel(ip); |
| 3402 | 3405 | ||
| 3403 | const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{ | 3406 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( |
| 3404 | .ty = Type.type, | 3407 | block, |
| 3405 | .val = Value.fromInterned(wip_ty.index), | 3408 | src, |
| 3406 | }, small.name_strategy, "opaque", inst); | 3409 | Value.fromInterned(wip_ty.index), |
| 3410 | small.name_strategy, | ||
| 3411 | "opaque", | ||
| 3412 | inst, | ||
| 3413 | ); | ||
| 3407 | mod.declPtr(new_decl_index).owns_tv = true; | 3414 | mod.declPtr(new_decl_index).owns_tv = true; |
| 3408 | errdefer mod.abortAnonDecl(new_decl_index); | 3415 | errdefer mod.abortAnonDecl(new_decl_index); |
| 3409 | 3416 | ||
| ... | @@ -3463,10 +3470,14 @@ fn zirErrorSetDecl( | ... | @@ -3463,10 +3470,14 @@ fn zirErrorSetDecl( |
| 3463 | 3470 | ||
| 3464 | const error_set_ty = try mod.errorSetFromUnsortedNames(names.keys()); | 3471 | const error_set_ty = try mod.errorSetFromUnsortedNames(names.keys()); |
| 3465 | 3472 | ||
| 3466 | const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{ | 3473 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( |
| 3467 | .ty = Type.type, | 3474 | block, |
| 3468 | .val = error_set_ty.toValue(), | 3475 | src, |
| 3469 | }, name_strategy, "error", inst); | 3476 | error_set_ty.toValue(), |
| 3477 | name_strategy, | ||
| 3478 | "error", | ||
| 3479 | inst, | ||
| 3480 | ); | ||
| 3470 | const new_decl = mod.declPtr(new_decl_index); | 3481 | const new_decl = mod.declPtr(new_decl_index); |
| 3471 | new_decl.owns_tv = true; | 3482 | new_decl.owns_tv = true; |
| 3472 | errdefer mod.abortAnonDecl(new_decl_index); | 3483 | errdefer mod.abortAnonDecl(new_decl_index); |
| ... | @@ -3762,10 +3773,10 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -3762,10 +3773,10 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3762 | if (!sema.isComptimeMutablePtr(ptr_val)) break :already_ct; | 3773 | if (!sema.isComptimeMutablePtr(ptr_val)) break :already_ct; |
| 3763 | const alloc_index = mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr.comptime_alloc; | 3774 | const alloc_index = mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr.comptime_alloc; |
| 3764 | const ct_alloc = sema.getComptimeAlloc(alloc_index); | 3775 | const ct_alloc = sema.getComptimeAlloc(alloc_index); |
| 3765 | const interned = try ct_alloc.val.intern(ct_alloc.ty, mod); | 3776 | const interned = try ct_alloc.val.intern(mod, sema.arena); |
| 3766 | if (Value.fromInterned(interned).canMutateComptimeVarState(mod)) { | 3777 | if (Value.fromInterned(interned).canMutateComptimeVarState(mod)) { |
| 3767 | // Preserve the comptime alloc, just make the pointer const. | 3778 | // Preserve the comptime alloc, just make the pointer const. |
| 3768 | ct_alloc.val = Value.fromInterned(interned); | 3779 | ct_alloc.val = .{ .interned = interned }; |
| 3769 | ct_alloc.is_const = true; | 3780 | ct_alloc.is_const = true; |
| 3770 | return sema.makePtrConst(block, alloc); | 3781 | return sema.makePtrConst(block, alloc); |
| 3771 | } else { | 3782 | } else { |
| ... | @@ -4030,7 +4041,7 @@ fn finishResolveComptimeKnownAllocPtr( | ... | @@ -4030,7 +4041,7 @@ fn finishResolveComptimeKnownAllocPtr( |
| 4030 | const alloc_index = existing_comptime_alloc orelse a: { | 4041 | const alloc_index = existing_comptime_alloc orelse a: { |
| 4031 | const idx = try sema.newComptimeAlloc(block, alloc_ty.childType(zcu), alloc_ty.ptrAlignment(zcu)); | 4042 | const idx = try sema.newComptimeAlloc(block, alloc_ty.childType(zcu), alloc_ty.ptrAlignment(zcu)); |
| 4032 | const alloc = sema.getComptimeAlloc(idx); | 4043 | const alloc = sema.getComptimeAlloc(idx); |
| 4033 | alloc.val = Value.fromInterned(result_val); | 4044 | alloc.val = .{ .interned = result_val }; |
| 4034 | break :a idx; | 4045 | break :a idx; |
| 4035 | }; | 4046 | }; |
| 4036 | sema.getComptimeAlloc(alloc_index).is_const = true; | 4047 | sema.getComptimeAlloc(alloc_index).is_const = true; |
| ... | @@ -4193,7 +4204,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -4193,7 +4204,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4193 | .anon_decl => |a| a.val, | 4204 | .anon_decl => |a| a.val, |
| 4194 | .comptime_alloc => |i| val: { | 4205 | .comptime_alloc => |i| val: { |
| 4195 | const alloc = sema.getComptimeAlloc(i); | 4206 | const alloc = sema.getComptimeAlloc(i); |
| 4196 | break :val try alloc.val.intern(alloc.ty, mod); | 4207 | break :val try alloc.val.intern(mod, sema.arena); |
| 4197 | }, | 4208 | }, |
| 4198 | else => unreachable, | 4209 | else => unreachable, |
| 4199 | }; | 4210 | }; |
| ... | @@ -4370,10 +4381,10 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -4370,10 +4381,10 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 4370 | .input_index = len_idx, | 4381 | .input_index = len_idx, |
| 4371 | } }; | 4382 | } }; |
| 4372 | try sema.errNote(block, a_src, msg, "length {} here", .{ | 4383 | try sema.errNote(block, a_src, msg, "length {} here", .{ |
| 4373 | v.fmtValue(Type.usize, sema.mod), | 4384 | v.fmtValue(sema.mod), |
| 4374 | }); | 4385 | }); |
| 4375 | try sema.errNote(block, arg_src, msg, "length {} here", .{ | 4386 | try sema.errNote(block, arg_src, msg, "length {} here", .{ |
| 4376 | arg_val.fmtValue(Type.usize, sema.mod), | 4387 | arg_val.fmtValue(sema.mod), |
| 4377 | }); | 4388 | }); |
| 4378 | break :msg msg; | 4389 | break :msg msg; |
| 4379 | }; | 4390 | }; |
| ... | @@ -5597,7 +5608,7 @@ fn storeToInferredAllocComptime( | ... | @@ -5597,7 +5608,7 @@ fn storeToInferredAllocComptime( |
| 5597 | } }); | 5608 | } }); |
| 5598 | } else { | 5609 | } else { |
| 5599 | const alloc_index = try sema.newComptimeAlloc(block, operand_ty, iac.alignment); | 5610 | const alloc_index = try sema.newComptimeAlloc(block, operand_ty, iac.alignment); |
| 5600 | sema.getComptimeAlloc(alloc_index).val = operand_val; | 5611 | sema.getComptimeAlloc(alloc_index).val = .{ .interned = operand_val.toIntern() }; |
| 5601 | iac.ptr = try zcu.intern(.{ .ptr = .{ | 5612 | iac.ptr = try zcu.intern(.{ .ptr = .{ |
| 5602 | .ty = alloc_ty.toIntern(), | 5613 | .ty = alloc_ty.toIntern(), |
| 5603 | .addr = .{ .comptime_alloc = alloc_index }, | 5614 | .addr = .{ .comptime_alloc = alloc_index }, |
| ... | @@ -5783,7 +5794,7 @@ fn zirCompileLog( | ... | @@ -5783,7 +5794,7 @@ fn zirCompileLog( |
| 5783 | const arg_ty = sema.typeOf(arg); | 5794 | const arg_ty = sema.typeOf(arg); |
| 5784 | if (try sema.resolveValueResolveLazy(arg)) |val| { | 5795 | if (try sema.resolveValueResolveLazy(arg)) |val| { |
| 5785 | try writer.print("@as({}, {})", .{ | 5796 | try writer.print("@as({}, {})", .{ |
| 5786 | arg_ty.fmt(mod), val.fmtValue(arg_ty, mod), | 5797 | arg_ty.fmt(mod), val.fmtValue(mod), |
| 5787 | }); | 5798 | }); |
| 5788 | } else { | 5799 | } else { |
| 5789 | try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(mod)}); | 5800 | try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(mod)}); |
| ... | @@ -6395,7 +6406,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -6395,7 +6406,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 6395 | const options = try sema.resolveExportOptions(block, options_src, extra.options); | 6406 | const options = try sema.resolveExportOptions(block, options_src, extra.options); |
| 6396 | if (options.linkage == .internal) | 6407 | if (options.linkage == .internal) |
| 6397 | return; | 6408 | return; |
| 6398 | if (operand.val.getFunction(mod)) |function| { | 6409 | if (operand.getFunction(mod)) |function| { |
| 6399 | const decl_index = function.owner_decl; | 6410 | const decl_index = function.owner_decl; |
| 6400 | return sema.analyzeExport(block, src, options, decl_index); | 6411 | return sema.analyzeExport(block, src, options, decl_index); |
| 6401 | } | 6412 | } |
| ... | @@ -6405,7 +6416,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -6405,7 +6416,7 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 6405 | .src = src, | 6416 | .src = src, |
| 6406 | .owner_decl = sema.owner_decl_index, | 6417 | .owner_decl = sema.owner_decl_index, |
| 6407 | .src_decl = block.src_decl, | 6418 | .src_decl = block.src_decl, |
| 6408 | .exported = .{ .value = operand.val.toIntern() }, | 6419 | .exported = .{ .value = operand.toIntern() }, |
| 6409 | .status = .in_progress, | 6420 | .status = .in_progress, |
| 6410 | }); | 6421 | }); |
| 6411 | } | 6422 | } |
| ... | @@ -6425,16 +6436,17 @@ pub fn analyzeExport( | ... | @@ -6425,16 +6436,17 @@ pub fn analyzeExport( |
| 6425 | 6436 | ||
| 6426 | try mod.ensureDeclAnalyzed(exported_decl_index); | 6437 | try mod.ensureDeclAnalyzed(exported_decl_index); |
| 6427 | const exported_decl = mod.declPtr(exported_decl_index); | 6438 | const exported_decl = mod.declPtr(exported_decl_index); |
| 6439 | const export_ty = exported_decl.typeOf(mod); | ||
| 6428 | 6440 | ||
| 6429 | if (!try sema.validateExternType(exported_decl.ty, .other)) { | 6441 | if (!try sema.validateExternType(export_ty, .other)) { |
| 6430 | const msg = msg: { | 6442 | const msg = msg: { |
| 6431 | const msg = try sema.errMsg(block, src, "unable to export type '{}'", .{exported_decl.ty.fmt(mod)}); | 6443 | const msg = try sema.errMsg(block, src, "unable to export type '{}'", .{export_ty.fmt(mod)}); |
| 6432 | errdefer msg.destroy(gpa); | 6444 | errdefer msg.destroy(gpa); |
| 6433 | 6445 | ||
| 6434 | const src_decl = mod.declPtr(block.src_decl); | 6446 | const src_decl = mod.declPtr(block.src_decl); |
| 6435 | try sema.explainWhyTypeIsNotExtern(msg, src_decl.toSrcLoc(src, mod), exported_decl.ty, .other); | 6447 | try sema.explainWhyTypeIsNotExtern(msg, src_decl.toSrcLoc(src, mod), export_ty, .other); |
| 6436 | 6448 | ||
| 6437 | try sema.addDeclaredHereNote(msg, exported_decl.ty); | 6449 | try sema.addDeclaredHereNote(msg, export_ty); |
| 6438 | break :msg msg; | 6450 | break :msg msg; |
| 6439 | }; | 6451 | }; |
| 6440 | return sema.failWithOwnedErrorMsg(block, msg); | 6452 | return sema.failWithOwnedErrorMsg(block, msg); |
| ... | @@ -6445,8 +6457,6 @@ pub fn analyzeExport( | ... | @@ -6445,8 +6457,6 @@ pub fn analyzeExport( |
| 6445 | return sema.fail(block, src, "export target cannot be extern", .{}); | 6457 | return sema.fail(block, src, "export target cannot be extern", .{}); |
| 6446 | } | 6458 | } |
| 6447 | 6459 | ||
| 6448 | // This decl is alive no matter what, since it's being exported | ||
| 6449 | try mod.markDeclAlive(exported_decl); | ||
| 6450 | try sema.maybeQueueFuncBodyAnalysis(exported_decl_index); | 6460 | try sema.maybeQueueFuncBodyAnalysis(exported_decl_index); |
| 6451 | 6461 | ||
| 6452 | try addExport(mod, .{ | 6462 | try addExport(mod, .{ |
| ... | @@ -6503,7 +6513,7 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst | ... | @@ -6503,7 +6513,7 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst |
| 6503 | } | 6513 | } |
| 6504 | 6514 | ||
| 6505 | const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index); | 6515 | const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index); |
| 6506 | switch (fn_owner_decl.ty.fnCallingConvention(mod)) { | 6516 | switch (fn_owner_decl.typeOf(mod).fnCallingConvention(mod)) { |
| 6507 | .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}), | 6517 | .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}), |
| 6508 | .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}), | 6518 | .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}), |
| 6509 | else => if (block.inlining != null) { | 6519 | else => if (block.inlining != null) { |
| ... | @@ -7692,7 +7702,7 @@ fn analyzeCall( | ... | @@ -7692,7 +7702,7 @@ fn analyzeCall( |
| 7692 | // comptime memory is mutated. | 7702 | // comptime memory is mutated. |
| 7693 | const memoized_arg_values = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len); | 7703 | const memoized_arg_values = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len); |
| 7694 | 7704 | ||
| 7695 | const owner_info = mod.typeToFunc(fn_owner_decl.ty).?; | 7705 | const owner_info = mod.typeToFunc(fn_owner_decl.typeOf(mod)).?; |
| 7696 | const new_param_types = try sema.arena.alloc(InternPool.Index, owner_info.param_types.len); | 7706 | const new_param_types = try sema.arena.alloc(InternPool.Index, owner_info.param_types.len); |
| 7697 | var new_fn_info: InternPool.GetFuncTypeKey = .{ | 7707 | var new_fn_info: InternPool.GetFuncTypeKey = .{ |
| 7698 | .param_types = new_param_types, | 7708 | .param_types = new_param_types, |
| ... | @@ -7835,7 +7845,7 @@ fn analyzeCall( | ... | @@ -7835,7 +7845,7 @@ fn analyzeCall( |
| 7835 | 7845 | ||
| 7836 | if (is_comptime_call) { | 7846 | if (is_comptime_call) { |
| 7837 | const result_val = try sema.resolveConstValue(block, .unneeded, result, undefined); | 7847 | const result_val = try sema.resolveConstValue(block, .unneeded, result, undefined); |
| 7838 | const result_interned = try result_val.intern2(sema.fn_ret_ty, mod); | 7848 | const result_interned = result_val.toIntern(); |
| 7839 | 7849 | ||
| 7840 | // Transform ad-hoc inferred error set types into concrete error sets. | 7850 | // Transform ad-hoc inferred error set types into concrete error sets. |
| 7841 | const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_interned); | 7851 | const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_interned); |
| ... | @@ -7856,8 +7866,7 @@ fn analyzeCall( | ... | @@ -7856,8 +7866,7 @@ fn analyzeCall( |
| 7856 | } | 7866 | } |
| 7857 | 7867 | ||
| 7858 | if (try sema.resolveValue(result)) |result_val| { | 7868 | if (try sema.resolveValue(result)) |result_val| { |
| 7859 | const result_interned = try result_val.intern2(sema.fn_ret_ty, mod); | 7869 | const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_val.toIntern()); |
| 7860 | const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_interned); | ||
| 7861 | break :res2 Air.internedToRef(result_transformed); | 7870 | break :res2 Air.internedToRef(result_transformed); |
| 7862 | } | 7871 | } |
| 7863 | 7872 | ||
| ... | @@ -7960,9 +7969,9 @@ fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Typ | ... | @@ -7960,9 +7969,9 @@ fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Typ |
| 7960 | }); | 7969 | }); |
| 7961 | } | 7970 | } |
| 7962 | const func_decl = mod.funcOwnerDeclPtr(sema.owner_func_index); | 7971 | const func_decl = mod.funcOwnerDeclPtr(sema.owner_func_index); |
| 7963 | if (!func_ty.eql(func_decl.ty, mod)) { | 7972 | if (!func_ty.eql(func_decl.typeOf(mod), mod)) { |
| 7964 | return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{ | 7973 | return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{ |
| 7965 | func_ty.fmt(mod), func_decl.ty.fmt(mod), | 7974 | func_ty.fmt(mod), func_decl.typeOf(mod).fmt(mod), |
| 7966 | }); | 7975 | }); |
| 7967 | } | 7976 | } |
| 7968 | _ = try block.addUnOp(.ret, result); | 7977 | _ = try block.addUnOp(.ret, result); |
| ... | @@ -8042,7 +8051,7 @@ fn analyzeInlineCallArg( | ... | @@ -8042,7 +8051,7 @@ fn analyzeInlineCallArg( |
| 8042 | // when the hash function is called. | 8051 | // when the hash function is called. |
| 8043 | const resolved_arg_val = try ics.caller().resolveLazyValue(arg_val); | 8052 | const resolved_arg_val = try ics.caller().resolveLazyValue(arg_val); |
| 8044 | should_memoize.* = should_memoize.* and !resolved_arg_val.canMutateComptimeVarState(mod); | 8053 | should_memoize.* = should_memoize.* and !resolved_arg_val.canMutateComptimeVarState(mod); |
| 8045 | memoized_arg_values[arg_i.*] = try resolved_arg_val.intern(Type.fromInterned(param_ty), mod); | 8054 | memoized_arg_values[arg_i.*] = resolved_arg_val.toIntern(); |
| 8046 | } else { | 8055 | } else { |
| 8047 | ics.callee().inst_map.putAssumeCapacityNoClobber(inst, casted_arg); | 8056 | ics.callee().inst_map.putAssumeCapacityNoClobber(inst, casted_arg); |
| 8048 | } | 8057 | } |
| ... | @@ -8081,7 +8090,7 @@ fn analyzeInlineCallArg( | ... | @@ -8081,7 +8090,7 @@ fn analyzeInlineCallArg( |
| 8081 | // when the hash function is called. | 8090 | // when the hash function is called. |
| 8082 | const resolved_arg_val = try ics.caller().resolveLazyValue(arg_val); | 8091 | const resolved_arg_val = try ics.caller().resolveLazyValue(arg_val); |
| 8083 | should_memoize.* = should_memoize.* and !resolved_arg_val.canMutateComptimeVarState(mod); | 8092 | should_memoize.* = should_memoize.* and !resolved_arg_val.canMutateComptimeVarState(mod); |
| 8084 | memoized_arg_values[arg_i.*] = try resolved_arg_val.intern(ics.caller().typeOf(uncasted_arg), mod); | 8093 | memoized_arg_values[arg_i.*] = resolved_arg_val.toIntern(); |
| 8085 | } else { | 8094 | } else { |
| 8086 | if (zir_tags[@intFromEnum(inst)] == .param_anytype_comptime) { | 8095 | if (zir_tags[@intFromEnum(inst)] == .param_anytype_comptime) { |
| 8087 | _ = try ics.caller().resolveConstValue(arg_block, arg_src, uncasted_arg, .{ | 8096 | _ = try ics.caller().resolveConstValue(arg_block, arg_src, uncasted_arg, .{ |
| ... | @@ -8871,7 +8880,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8871,7 +8880,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8871 | return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern()); | 8880 | return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern()); |
| 8872 | } | 8881 | } |
| 8873 | return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{ | 8882 | return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{ |
| 8874 | int_val.fmtValue(sema.typeOf(operand), mod), dest_ty.fmt(mod), | 8883 | int_val.fmtValue(mod), dest_ty.fmt(mod), |
| 8875 | }); | 8884 | }); |
| 8876 | } | 8885 | } |
| 8877 | if (int_val.isUndef(mod)) { | 8886 | if (int_val.isUndef(mod)) { |
| ... | @@ -8879,7 +8888,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8879,7 +8888,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8879 | } | 8888 | } |
| 8880 | if (!(try sema.enumHasInt(dest_ty, int_val))) { | 8889 | if (!(try sema.enumHasInt(dest_ty, int_val))) { |
| 8881 | return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{ | 8890 | return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{ |
| 8882 | dest_ty.fmt(mod), int_val.fmtValue(sema.typeOf(operand), mod), | 8891 | dest_ty.fmt(mod), int_val.fmtValue(mod), |
| 8883 | }); | 8892 | }); |
| 8884 | } | 8893 | } |
| 8885 | return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern()); | 8894 | return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern()); |
| ... | @@ -13925,7 +13934,7 @@ fn zirShl( | ... | @@ -13925,7 +13934,7 @@ fn zirShl( |
| 13925 | const rhs_elem = try rhs_val.elemValue(mod, i); | 13934 | const rhs_elem = try rhs_val.elemValue(mod, i); |
| 13926 | if (rhs_elem.compareHetero(.gte, bit_value, mod)) { | 13935 | if (rhs_elem.compareHetero(.gte, bit_value, mod)) { |
| 13927 | return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ | 13936 | return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ |
| 13928 | rhs_elem.fmtValue(scalar_ty, mod), | 13937 | rhs_elem.fmtValue(mod), |
| 13929 | i, | 13938 | i, |
| 13930 | scalar_ty.fmt(mod), | 13939 | scalar_ty.fmt(mod), |
| 13931 | }); | 13940 | }); |
| ... | @@ -13933,7 +13942,7 @@ fn zirShl( | ... | @@ -13933,7 +13942,7 @@ fn zirShl( |
| 13933 | } | 13942 | } |
| 13934 | } else if (rhs_val.compareHetero(.gte, bit_value, mod)) { | 13943 | } else if (rhs_val.compareHetero(.gte, bit_value, mod)) { |
| 13935 | return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ | 13944 | return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ |
| 13936 | rhs_val.fmtValue(scalar_ty, mod), | 13945 | rhs_val.fmtValue(mod), |
| 13937 | scalar_ty.fmt(mod), | 13946 | scalar_ty.fmt(mod), |
| 13938 | }); | 13947 | }); |
| 13939 | } | 13948 | } |
| ... | @@ -13944,14 +13953,14 @@ fn zirShl( | ... | @@ -13944,14 +13953,14 @@ fn zirShl( |
| 13944 | const rhs_elem = try rhs_val.elemValue(mod, i); | 13953 | const rhs_elem = try rhs_val.elemValue(mod, i); |
| 13945 | if (rhs_elem.compareHetero(.lt, try mod.intValue(scalar_rhs_ty, 0), mod)) { | 13954 | if (rhs_elem.compareHetero(.lt, try mod.intValue(scalar_rhs_ty, 0), mod)) { |
| 13946 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ | 13955 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ |
| 13947 | rhs_elem.fmtValue(scalar_ty, mod), | 13956 | rhs_elem.fmtValue(mod), |
| 13948 | i, | 13957 | i, |
| 13949 | }); | 13958 | }); |
| 13950 | } | 13959 | } |
| 13951 | } | 13960 | } |
| 13952 | } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) { | 13961 | } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) { |
| 13953 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ | 13962 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ |
| 13954 | rhs_val.fmtValue(scalar_ty, mod), | 13963 | rhs_val.fmtValue(mod), |
| 13955 | }); | 13964 | }); |
| 13956 | } | 13965 | } |
| 13957 | } | 13966 | } |
| ... | @@ -14090,7 +14099,7 @@ fn zirShr( | ... | @@ -14090,7 +14099,7 @@ fn zirShr( |
| 14090 | const rhs_elem = try rhs_val.elemValue(mod, i); | 14099 | const rhs_elem = try rhs_val.elemValue(mod, i); |
| 14091 | if (rhs_elem.compareHetero(.gte, bit_value, mod)) { | 14100 | if (rhs_elem.compareHetero(.gte, bit_value, mod)) { |
| 14092 | return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ | 14101 | return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ |
| 14093 | rhs_elem.fmtValue(scalar_ty, mod), | 14102 | rhs_elem.fmtValue(mod), |
| 14094 | i, | 14103 | i, |
| 14095 | scalar_ty.fmt(mod), | 14104 | scalar_ty.fmt(mod), |
| 14096 | }); | 14105 | }); |
| ... | @@ -14098,7 +14107,7 @@ fn zirShr( | ... | @@ -14098,7 +14107,7 @@ fn zirShr( |
| 14098 | } | 14107 | } |
| 14099 | } else if (rhs_val.compareHetero(.gte, bit_value, mod)) { | 14108 | } else if (rhs_val.compareHetero(.gte, bit_value, mod)) { |
| 14100 | return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ | 14109 | return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ |
| 14101 | rhs_val.fmtValue(scalar_ty, mod), | 14110 | rhs_val.fmtValue(mod), |
| 14102 | scalar_ty.fmt(mod), | 14111 | scalar_ty.fmt(mod), |
| 14103 | }); | 14112 | }); |
| 14104 | } | 14113 | } |
| ... | @@ -14109,14 +14118,14 @@ fn zirShr( | ... | @@ -14109,14 +14118,14 @@ fn zirShr( |
| 14109 | const rhs_elem = try rhs_val.elemValue(mod, i); | 14118 | const rhs_elem = try rhs_val.elemValue(mod, i); |
| 14110 | if (rhs_elem.compareHetero(.lt, try mod.intValue(rhs_ty.childType(mod), 0), mod)) { | 14119 | if (rhs_elem.compareHetero(.lt, try mod.intValue(rhs_ty.childType(mod), 0), mod)) { |
| 14111 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ | 14120 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ |
| 14112 | rhs_elem.fmtValue(scalar_ty, mod), | 14121 | rhs_elem.fmtValue(mod), |
| 14113 | i, | 14122 | i, |
| 14114 | }); | 14123 | }); |
| 14115 | } | 14124 | } |
| 14116 | } | 14125 | } |
| 14117 | } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) { | 14126 | } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) { |
| 14118 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ | 14127 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ |
| 14119 | rhs_val.fmtValue(scalar_ty, mod), | 14128 | rhs_val.fmtValue(mod), |
| 14120 | }); | 14129 | }); |
| 14121 | } | 14130 | } |
| 14122 | if (maybe_lhs_val) |lhs_val| { | 14131 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -14270,7 +14279,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -14270,7 +14279,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 14270 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); | 14279 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 14271 | for (elems, 0..) |*elem, i| { | 14280 | for (elems, 0..) |*elem, i| { |
| 14272 | const elem_val = try val.elemValue(mod, i); | 14281 | const elem_val = try val.elemValue(mod, i); |
| 14273 | elem.* = try (try elem_val.bitwiseNot(scalar_type, sema.arena, mod)).intern(scalar_type, mod); | 14282 | elem.* = (try elem_val.bitwiseNot(scalar_type, sema.arena, mod)).toIntern(); |
| 14274 | } | 14283 | } |
| 14275 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 14284 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ |
| 14276 | .ty = operand_type.toIntern(), | 14285 | .ty = operand_type.toIntern(), |
| ... | @@ -14499,12 +14508,16 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14499,12 +14508,16 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14499 | else => unreachable, | 14508 | else => unreachable, |
| 14500 | }) |rhs_val| { | 14509 | }) |rhs_val| { |
| 14501 | const lhs_sub_val = if (lhs_ty.isSinglePointer(mod)) | 14510 | const lhs_sub_val = if (lhs_ty.isSinglePointer(mod)) |
| 14502 | (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).? | 14511 | try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty) orelse break :rs lhs_src |
| 14512 | else if (lhs_ty.isSlice(mod)) | ||
| 14513 | try sema.maybeDerefSliceAsArray(block, lhs_src, lhs_val) orelse break :rs lhs_src | ||
| 14503 | else | 14514 | else |
| 14504 | lhs_val; | 14515 | lhs_val; |
| 14505 | 14516 | ||
| 14506 | const rhs_sub_val = if (rhs_ty.isSinglePointer(mod)) | 14517 | const rhs_sub_val = if (rhs_ty.isSinglePointer(mod)) |
| 14507 | (try sema.pointerDeref(block, rhs_src, rhs_val, rhs_ty)).? | 14518 | try sema.pointerDeref(block, rhs_src, rhs_val, rhs_ty) orelse break :rs rhs_src |
| 14519 | else if (rhs_ty.isSlice(mod)) | ||
| 14520 | try sema.maybeDerefSliceAsArray(block, rhs_src, rhs_val) orelse break :rs rhs_src | ||
| 14508 | else | 14521 | else |
| 14509 | rhs_val; | 14522 | rhs_val; |
| 14510 | 14523 | ||
| ... | @@ -14521,7 +14534,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14521,7 +14534,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14521 | } }; | 14534 | } }; |
| 14522 | const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src); | 14535 | const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src); |
| 14523 | const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined); | 14536 | const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined); |
| 14524 | element_vals[elem_i] = try coerced_elem_val.intern(resolved_elem_ty, mod); | 14537 | element_vals[elem_i] = coerced_elem_val.toIntern(); |
| 14525 | } | 14538 | } |
| 14526 | while (elem_i < result_len) : (elem_i += 1) { | 14539 | while (elem_i < result_len) : (elem_i += 1) { |
| 14527 | const rhs_elem_i = elem_i - lhs_len; | 14540 | const rhs_elem_i = elem_i - lhs_len; |
| ... | @@ -14534,7 +14547,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14534,7 +14547,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14534 | } }; | 14547 | } }; |
| 14535 | const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src); | 14548 | const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src); |
| 14536 | const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined); | 14549 | const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined); |
| 14537 | element_vals[elem_i] = try coerced_elem_val.intern(resolved_elem_ty, mod); | 14550 | element_vals[elem_i] = coerced_elem_val.toIntern(); |
| 14538 | } | 14551 | } |
| 14539 | return sema.addConstantMaybeRef(try mod.intern(.{ .aggregate = .{ | 14552 | return sema.addConstantMaybeRef(try mod.intern(.{ .aggregate = .{ |
| 14540 | .ty = result_ty.toIntern(), | 14553 | .ty = result_ty.toIntern(), |
| ... | @@ -14624,10 +14637,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins | ... | @@ -14624,10 +14637,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins |
| 14624 | .Pointer => { | 14637 | .Pointer => { |
| 14625 | const ptr_info = operand_ty.ptrInfo(mod); | 14638 | const ptr_info = operand_ty.ptrInfo(mod); |
| 14626 | switch (ptr_info.flags.size) { | 14639 | switch (ptr_info.flags.size) { |
| 14627 | // TODO: in the Many case here this should only work if the type | 14640 | .Slice => { |
| 14628 | // has a sentinel, and this code should compute the length based | ||
| 14629 | // on the sentinel value. | ||
| 14630 | .Slice, .Many => { | ||
| 14631 | const val = try sema.resolveConstDefinedValue(block, src, operand, .{ | 14641 | const val = try sema.resolveConstDefinedValue(block, src, operand, .{ |
| 14632 | .needed_comptime_reason = "slice value being concatenated must be comptime-known", | 14642 | .needed_comptime_reason = "slice value being concatenated must be comptime-known", |
| 14633 | }); | 14643 | }); |
| ... | @@ -14637,7 +14647,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins | ... | @@ -14637,7 +14647,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins |
| 14637 | .none => null, | 14647 | .none => null, |
| 14638 | else => Value.fromInterned(ptr_info.sentinel), | 14648 | else => Value.fromInterned(ptr_info.sentinel), |
| 14639 | }, | 14649 | }, |
| 14640 | .len = val.sliceLen(mod), | 14650 | .len = try val.sliceLen(sema), |
| 14641 | }; | 14651 | }; |
| 14642 | }, | 14652 | }, |
| 14643 | .One => { | 14653 | .One => { |
| ... | @@ -14645,7 +14655,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins | ... | @@ -14645,7 +14655,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins |
| 14645 | return Type.fromInterned(ptr_info.child).arrayInfo(mod); | 14655 | return Type.fromInterned(ptr_info.child).arrayInfo(mod); |
| 14646 | } | 14656 | } |
| 14647 | }, | 14657 | }, |
| 14648 | .C => {}, | 14658 | .C, .Many => {}, |
| 14649 | } | 14659 | } |
| 14650 | }, | 14660 | }, |
| 14651 | .Struct => { | 14661 | .Struct => { |
| ... | @@ -14831,9 +14841,11 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14831,9 +14841,11 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14831 | const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace(mod) else null; | 14841 | const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace(mod) else null; |
| 14832 | const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len); | 14842 | const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len); |
| 14833 | 14843 | ||
| 14834 | if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| { | 14844 | if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| ct: { |
| 14835 | const lhs_sub_val = if (lhs_ty.isSinglePointer(mod)) | 14845 | const lhs_sub_val = if (lhs_ty.isSinglePointer(mod)) |
| 14836 | (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).? | 14846 | try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty) orelse break :ct |
| 14847 | else if (lhs_ty.isSlice(mod)) | ||
| 14848 | try sema.maybeDerefSliceAsArray(block, lhs_src, lhs_val) orelse break :ct | ||
| 14837 | else | 14849 | else |
| 14838 | lhs_val; | 14850 | lhs_val; |
| 14839 | 14851 | ||
| ... | @@ -14841,7 +14853,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14841,7 +14853,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14841 | // Optimization for the common pattern of a single element repeated N times, such | 14853 | // Optimization for the common pattern of a single element repeated N times, such |
| 14842 | // as zero-filling a byte array. | 14854 | // as zero-filling a byte array. |
| 14843 | if (lhs_len == 1 and lhs_info.sentinel == null) { | 14855 | if (lhs_len == 1 and lhs_info.sentinel == null) { |
| 14844 | const elem_val = (try lhs_sub_val.maybeElemValueFull(sema, mod, 0)).?; | 14856 | const elem_val = try lhs_sub_val.elemValue(mod, 0); |
| 14845 | break :v try mod.intern(.{ .aggregate = .{ | 14857 | break :v try mod.intern(.{ .aggregate = .{ |
| 14846 | .ty = result_ty.toIntern(), | 14858 | .ty = result_ty.toIntern(), |
| 14847 | .storage = .{ .repeated_elem = elem_val.toIntern() }, | 14859 | .storage = .{ .repeated_elem = elem_val.toIntern() }, |
| ... | @@ -14853,7 +14865,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -14853,7 +14865,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 14853 | while (elem_i < result_len) { | 14865 | while (elem_i < result_len) { |
| 14854 | var lhs_i: usize = 0; | 14866 | var lhs_i: usize = 0; |
| 14855 | while (lhs_i < lhs_len) : (lhs_i += 1) { | 14867 | while (lhs_i < lhs_len) : (lhs_i += 1) { |
| 14856 | const elem_val = (try lhs_sub_val.maybeElemValueFull(sema, mod, lhs_i)).?; | 14868 | const elem_val = try lhs_sub_val.elemValue(mod, lhs_i); |
| 14857 | element_vals[elem_i] = elem_val.toIntern(); | 14869 | element_vals[elem_i] = elem_val.toIntern(); |
| 14858 | elem_i += 1; | 14870 | elem_i += 1; |
| 14859 | } | 14871 | } |
| ... | @@ -15034,7 +15046,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -15034,7 +15046,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 15034 | block, | 15046 | block, |
| 15035 | src, | 15047 | src, |
| 15036 | "ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'", | 15048 | "ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'", |
| 15037 | .{ lhs_ty.fmt(mod), rhs_ty.fmt(mod), rem.fmtValue(resolved_type, mod) }, | 15049 | .{ lhs_ty.fmt(mod), rhs_ty.fmt(mod), rem.fmtValue(mod) }, |
| 15038 | ); | 15050 | ); |
| 15039 | } | 15051 | } |
| 15040 | } | 15052 | } |
| ... | @@ -15813,7 +15825,7 @@ fn intRem( | ... | @@ -15813,7 +15825,7 @@ fn intRem( |
| 15813 | for (result_data, 0..) |*scalar, i| { | 15825 | for (result_data, 0..) |*scalar, i| { |
| 15814 | const lhs_elem = try lhs.elemValue(mod, i); | 15826 | const lhs_elem = try lhs.elemValue(mod, i); |
| 15815 | const rhs_elem = try rhs.elemValue(mod, i); | 15827 | const rhs_elem = try rhs.elemValue(mod, i); |
| 15816 | scalar.* = try (try sema.intRemScalar(lhs_elem, rhs_elem, scalar_ty)).intern(scalar_ty, mod); | 15828 | scalar.* = (try sema.intRemScalar(lhs_elem, rhs_elem, scalar_ty)).toIntern(); |
| 15817 | } | 15829 | } |
| 15818 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 15830 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 15819 | .ty = ty.toIntern(), | 15831 | .ty = ty.toIntern(), |
| ... | @@ -17753,7 +17765,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17753,7 +17765,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17753 | const info = ty.intInfo(mod); | 17765 | const info = ty.intInfo(mod); |
| 17754 | const field_values = .{ | 17766 | const field_values = .{ |
| 17755 | // signedness: Signedness, | 17767 | // signedness: Signedness, |
| 17756 | try (try mod.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).intern(signedness_ty, mod), | 17768 | (try mod.enumValueFieldIndex(signedness_ty, @intFromEnum(info.signedness))).toIntern(), |
| 17757 | // bits: u16, | 17769 | // bits: u16, |
| 17758 | (try mod.intValue(Type.u16, info.bits)).toIntern(), | 17770 | (try mod.intValue(Type.u16, info.bits)).toIntern(), |
| 17759 | }; | 17771 | }; |
| ... | @@ -17823,7 +17835,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17823,7 +17835,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17823 | 17835 | ||
| 17824 | const field_values = .{ | 17836 | const field_values = .{ |
| 17825 | // size: Size, | 17837 | // size: Size, |
| 17826 | try (try mod.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).intern(ptr_size_ty, mod), | 17838 | (try mod.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).toIntern(), |
| 17827 | // is_const: bool, | 17839 | // is_const: bool, |
| 17828 | Value.makeBool(info.flags.is_const).toIntern(), | 17840 | Value.makeBool(info.flags.is_const).toIntern(), |
| 17829 | // is_volatile: bool, | 17841 | // is_volatile: bool, |
| ... | @@ -17831,7 +17843,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17831,7 +17843,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17831 | // alignment: comptime_int, | 17843 | // alignment: comptime_int, |
| 17832 | alignment.toIntern(), | 17844 | alignment.toIntern(), |
| 17833 | // address_space: AddressSpace | 17845 | // address_space: AddressSpace |
| 17834 | try (try mod.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).intern(addrspace_ty, mod), | 17846 | (try mod.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).toIntern(), |
| 17835 | // child: type, | 17847 | // child: type, |
| 17836 | info.child, | 17848 | info.child, |
| 17837 | // is_allowzero: bool, | 17849 | // is_allowzero: bool, |
| ... | @@ -19975,8 +19987,8 @@ fn unionInit( | ... | @@ -19975,8 +19987,8 @@ fn unionInit( |
| 19975 | const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index); | 19987 | const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index); |
| 19976 | return Air.internedToRef((try mod.intern(.{ .un = .{ | 19988 | return Air.internedToRef((try mod.intern(.{ .un = .{ |
| 19977 | .ty = union_ty.toIntern(), | 19989 | .ty = union_ty.toIntern(), |
| 19978 | .tag = try tag_val.intern(tag_ty, mod), | 19990 | .tag = tag_val.toIntern(), |
| 19979 | .val = try init_val.intern(field_ty, mod), | 19991 | .val = init_val.toIntern(), |
| 19980 | } }))); | 19992 | } }))); |
| 19981 | } | 19993 | } |
| 19982 | 19994 | ||
| ... | @@ -20099,8 +20111,8 @@ fn zirStructInit( | ... | @@ -20099,8 +20111,8 @@ fn zirStructInit( |
| 20099 | if (try sema.resolveValue(init_inst)) |val| { | 20111 | if (try sema.resolveValue(init_inst)) |val| { |
| 20100 | const struct_val = Value.fromInterned((try mod.intern(.{ .un = .{ | 20112 | const struct_val = Value.fromInterned((try mod.intern(.{ .un = .{ |
| 20101 | .ty = resolved_ty.toIntern(), | 20113 | .ty = resolved_ty.toIntern(), |
| 20102 | .tag = try tag_val.intern(tag_ty, mod), | 20114 | .tag = tag_val.toIntern(), |
| 20103 | .val = try val.intern(field_ty, mod), | 20115 | .val = val.toIntern(), |
| 20104 | } }))); | 20116 | } }))); |
| 20105 | const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src); | 20117 | const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src); |
| 20106 | const final_val = (try sema.resolveValue(final_val_inst)).?; | 20118 | const final_val = (try sema.resolveValue(final_val_inst)).?; |
| ... | @@ -20400,7 +20412,7 @@ fn structInitAnon( | ... | @@ -20400,7 +20412,7 @@ fn structInitAnon( |
| 20400 | return sema.failWithOwnedErrorMsg(block, msg); | 20412 | return sema.failWithOwnedErrorMsg(block, msg); |
| 20401 | } | 20413 | } |
| 20402 | if (try sema.resolveValue(init)) |init_val| { | 20414 | if (try sema.resolveValue(init)) |init_val| { |
| 20403 | field_val.* = try init_val.intern(Type.fromInterned(field_ty.*), mod); | 20415 | field_val.* = init_val.toIntern(); |
| 20404 | } else { | 20416 | } else { |
| 20405 | field_val.* = .none; | 20417 | field_val.* = .none; |
| 20406 | runtime_index = @intCast(i_usize); | 20418 | runtime_index = @intCast(i_usize); |
| ... | @@ -20577,13 +20589,9 @@ fn zirArrayInit( | ... | @@ -20577,13 +20589,9 @@ fn zirArrayInit( |
| 20577 | 20589 | ||
| 20578 | const runtime_index = opt_runtime_index orelse { | 20590 | const runtime_index = opt_runtime_index orelse { |
| 20579 | const elem_vals = try sema.arena.alloc(InternPool.Index, resolved_args.len); | 20591 | const elem_vals = try sema.arena.alloc(InternPool.Index, resolved_args.len); |
| 20580 | for (elem_vals, resolved_args, 0..) |*val, arg, i| { | 20592 | for (elem_vals, resolved_args) |*val, arg| { |
| 20581 | const elem_ty = if (is_tuple) | ||
| 20582 | array_ty.structFieldType(i, mod) | ||
| 20583 | else | ||
| 20584 | array_ty.elemType2(mod); | ||
| 20585 | // We checked that all args are comptime above. | 20593 | // We checked that all args are comptime above. |
| 20586 | val.* = try ((sema.resolveValue(arg) catch unreachable).?).intern(elem_ty, mod); | 20594 | val.* = (sema.resolveValue(arg) catch unreachable).?.toIntern(); |
| 20587 | } | 20595 | } |
| 20588 | const arr_val = try mod.intern(.{ .aggregate = .{ | 20596 | const arr_val = try mod.intern(.{ .aggregate = .{ |
| 20589 | .ty = array_ty.toIntern(), | 20597 | .ty = array_ty.toIntern(), |
| ... | @@ -20998,7 +21006,7 @@ fn maybeConstantUnaryMath( | ... | @@ -20998,7 +21006,7 @@ fn maybeConstantUnaryMath( |
| 20998 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); | 21006 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 20999 | for (elems, 0..) |*elem, i| { | 21007 | for (elems, 0..) |*elem, i| { |
| 21000 | const elem_val = try val.elemValue(sema.mod, i); | 21008 | const elem_val = try val.elemValue(sema.mod, i); |
| 21001 | elem.* = try (try eval(elem_val, scalar_ty, sema.arena, sema.mod)).intern(scalar_ty, mod); | 21009 | elem.* = (try eval(elem_val, scalar_ty, sema.arena, sema.mod)).toIntern(); |
| 21002 | } | 21010 | } |
| 21003 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 21011 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ |
| 21004 | .ty = result_ty.toIntern(), | 21012 | .ty = result_ty.toIntern(), |
| ... | @@ -21086,7 +21094,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -21086,7 +21094,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 21086 | const enum_decl = mod.declPtr(enum_decl_index); | 21094 | const enum_decl = mod.declPtr(enum_decl_index); |
| 21087 | const msg = msg: { | 21095 | const msg = msg: { |
| 21088 | const msg = try sema.errMsg(block, src, "no field with value '{}' in enum '{}'", .{ | 21096 | const msg = try sema.errMsg(block, src, "no field with value '{}' in enum '{}'", .{ |
| 21089 | val.fmtValue(enum_ty, sema.mod), enum_decl.name.fmt(ip), | 21097 | val.fmtValue(sema.mod), enum_decl.name.fmt(ip), |
| 21090 | }); | 21098 | }); |
| 21091 | errdefer msg.destroy(sema.gpa); | 21099 | errdefer msg.destroy(sema.gpa); |
| 21092 | try mod.errNoteNonLazy(enum_decl.srcLoc(mod), msg, "declared here", .{}); | 21100 | try mod.errNoteNonLazy(enum_decl.srcLoc(mod), msg, "declared here", .{}); |
| ... | @@ -21129,7 +21137,9 @@ fn zirReify( | ... | @@ -21129,7 +21137,9 @@ fn zirReify( |
| 21129 | .needed_comptime_reason = "operand to @Type must be comptime-known", | 21137 | .needed_comptime_reason = "operand to @Type must be comptime-known", |
| 21130 | }); | 21138 | }); |
| 21131 | const union_val = ip.indexToKey(val.toIntern()).un; | 21139 | const union_val = ip.indexToKey(val.toIntern()).un; |
| 21132 | if (try sema.anyUndef(Value.fromInterned(union_val.val))) return sema.failWithUseOfUndef(block, src); | 21140 | if (try sema.anyUndef(block, operand_src, Value.fromInterned(union_val.val))) { |
| 21141 | return sema.failWithUseOfUndef(block, operand_src); | ||
| 21142 | } | ||
| 21133 | const tag_index = type_info_ty.unionTagFieldIndex(Value.fromInterned(union_val.tag), mod).?; | 21143 | const tag_index = type_info_ty.unionTagFieldIndex(Value.fromInterned(union_val.tag), mod).?; |
| 21134 | switch (@as(std.builtin.TypeId, @enumFromInt(tag_index))) { | 21144 | switch (@as(std.builtin.TypeId, @enumFromInt(tag_index))) { |
| 21135 | .Type => return .type_type, | 21145 | .Type => return .type_type, |
| ... | @@ -21370,11 +21380,15 @@ fn zirReify( | ... | @@ -21370,11 +21380,15 @@ fn zirReify( |
| 21370 | const payload_val = Value.fromInterned(union_val.val).optionalValue(mod) orelse | 21380 | const payload_val = Value.fromInterned(union_val.val).optionalValue(mod) orelse |
| 21371 | return Air.internedToRef(Type.anyerror.toIntern()); | 21381 | return Air.internedToRef(Type.anyerror.toIntern()); |
| 21372 | 21382 | ||
| 21373 | const len = try sema.usizeCast(block, src, payload_val.sliceLen(mod)); | 21383 | const names_val = try sema.derefSliceAsArray(block, src, payload_val, .{ |
| 21384 | .needed_comptime_reason = "error set contents must be comptime-known", | ||
| 21385 | }); | ||
| 21386 | |||
| 21387 | const len = try sema.usizeCast(block, src, names_val.typeOf(mod).arrayLen(mod)); | ||
| 21374 | var names: InferredErrorSet.NameMap = .{}; | 21388 | var names: InferredErrorSet.NameMap = .{}; |
| 21375 | try names.ensureUnusedCapacity(sema.arena, len); | 21389 | try names.ensureUnusedCapacity(sema.arena, len); |
| 21376 | for (0..len) |i| { | 21390 | for (0..len) |i| { |
| 21377 | const elem_val = (try payload_val.maybeElemValueFull(sema, mod, i)).?; | 21391 | const elem_val = try names_val.elemValue(mod, i); |
| 21378 | const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern())); | 21392 | const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern())); |
| 21379 | const name_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex( | 21393 | const name_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex( |
| 21380 | ip, | 21394 | ip, |
| ... | @@ -21422,7 +21436,7 @@ fn zirReify( | ... | @@ -21422,7 +21436,7 @@ fn zirReify( |
| 21422 | const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val); | 21436 | const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val); |
| 21423 | 21437 | ||
| 21424 | // Decls | 21438 | // Decls |
| 21425 | if (decls_val.sliceLen(mod) > 0) { | 21439 | if (try decls_val.sliceLen(sema) > 0) { |
| 21426 | return sema.fail(block, src, "reified structs must have no decls", .{}); | 21440 | return sema.fail(block, src, "reified structs must have no decls", .{}); |
| 21427 | } | 21441 | } |
| 21428 | 21442 | ||
| ... | @@ -21430,7 +21444,11 @@ fn zirReify( | ... | @@ -21430,7 +21444,11 @@ fn zirReify( |
| 21430 | return sema.fail(block, src, "non-packed struct does not support backing integer type", .{}); | 21444 | return sema.fail(block, src, "non-packed struct does not support backing integer type", .{}); |
| 21431 | } | 21445 | } |
| 21432 | 21446 | ||
| 21433 | return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_val, name_strategy, is_tuple_val.toBool()); | 21447 | const fields_arr = try sema.derefSliceAsArray(block, operand_src, fields_val, .{ |
| 21448 | .needed_comptime_reason = "struct fields must be comptime-known", | ||
| 21449 | }); | ||
| 21450 | |||
| 21451 | return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_arr, name_strategy, is_tuple_val.toBool()); | ||
| 21434 | }, | 21452 | }, |
| 21435 | .Enum => { | 21453 | .Enum => { |
| 21436 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21454 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| ... | @@ -21451,11 +21469,15 @@ fn zirReify( | ... | @@ -21451,11 +21469,15 @@ fn zirReify( |
| 21451 | try ip.getOrPutString(gpa, "is_exhaustive"), | 21469 | try ip.getOrPutString(gpa, "is_exhaustive"), |
| 21452 | ).?); | 21470 | ).?); |
| 21453 | 21471 | ||
| 21454 | if (decls_val.sliceLen(mod) > 0) { | 21472 | if (try decls_val.sliceLen(sema) > 0) { |
| 21455 | return sema.fail(block, src, "reified enums must have no decls", .{}); | 21473 | return sema.fail(block, src, "reified enums must have no decls", .{}); |
| 21456 | } | 21474 | } |
| 21457 | 21475 | ||
| 21458 | return sema.reifyEnum(block, inst, src, tag_type_val.toType(), is_exhaustive_val.toBool(), fields_val, name_strategy); | 21476 | const fields_arr = try sema.derefSliceAsArray(block, operand_src, fields_val, .{ |
| 21477 | .needed_comptime_reason = "enum fields must be comptime-known", | ||
| 21478 | }); | ||
| 21479 | |||
| 21480 | return sema.reifyEnum(block, inst, src, tag_type_val.toType(), is_exhaustive_val.toBool(), fields_arr, name_strategy); | ||
| 21459 | }, | 21481 | }, |
| 21460 | .Opaque => { | 21482 | .Opaque => { |
| 21461 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21483 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| ... | @@ -21465,7 +21487,7 @@ fn zirReify( | ... | @@ -21465,7 +21487,7 @@ fn zirReify( |
| 21465 | ).?); | 21487 | ).?); |
| 21466 | 21488 | ||
| 21467 | // Decls | 21489 | // Decls |
| 21468 | if (decls_val.sliceLen(mod) > 0) { | 21490 | if (try decls_val.sliceLen(sema) > 0) { |
| 21469 | return sema.fail(block, src, "reified opaque must have no decls", .{}); | 21491 | return sema.fail(block, src, "reified opaque must have no decls", .{}); |
| 21470 | } | 21492 | } |
| 21471 | 21493 | ||
| ... | @@ -21480,10 +21502,14 @@ fn zirReify( | ... | @@ -21480,10 +21502,14 @@ fn zirReify( |
| 21480 | }; | 21502 | }; |
| 21481 | errdefer wip_ty.cancel(ip); | 21503 | errdefer wip_ty.cancel(ip); |
| 21482 | 21504 | ||
| 21483 | const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{ | 21505 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( |
| 21484 | .ty = Type.type, | 21506 | block, |
| 21485 | .val = Value.fromInterned(wip_ty.index), | 21507 | src, |
| 21486 | }, name_strategy, "opaque", inst); | 21508 | Value.fromInterned(wip_ty.index), |
| 21509 | name_strategy, | ||
| 21510 | "opaque", | ||
| 21511 | inst, | ||
| 21512 | ); | ||
| 21487 | mod.declPtr(new_decl_index).owns_tv = true; | 21513 | mod.declPtr(new_decl_index).owns_tv = true; |
| 21488 | errdefer mod.abortAnonDecl(new_decl_index); | 21514 | errdefer mod.abortAnonDecl(new_decl_index); |
| 21489 | 21515 | ||
| ... | @@ -21510,12 +21536,16 @@ fn zirReify( | ... | @@ -21510,12 +21536,16 @@ fn zirReify( |
| 21510 | try ip.getOrPutString(gpa, "decls"), | 21536 | try ip.getOrPutString(gpa, "decls"), |
| 21511 | ).?); | 21537 | ).?); |
| 21512 | 21538 | ||
| 21513 | if (decls_val.sliceLen(mod) > 0) { | 21539 | if (try decls_val.sliceLen(sema) > 0) { |
| 21514 | return sema.fail(block, src, "reified unions must have no decls", .{}); | 21540 | return sema.fail(block, src, "reified unions must have no decls", .{}); |
| 21515 | } | 21541 | } |
| 21516 | const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val); | 21542 | const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val); |
| 21517 | 21543 | ||
| 21518 | return sema.reifyUnion(block, inst, src, layout, tag_type_val, fields_val, name_strategy); | 21544 | const fields_arr = try sema.derefSliceAsArray(block, operand_src, fields_val, .{ |
| 21545 | .needed_comptime_reason = "union fields must be comptime-known", | ||
| 21546 | }); | ||
| 21547 | |||
| 21548 | return sema.reifyUnion(block, inst, src, layout, tag_type_val, fields_arr, name_strategy); | ||
| 21519 | }, | 21549 | }, |
| 21520 | .Fn => { | 21550 | .Fn => { |
| 21521 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21551 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| ... | @@ -21535,7 +21565,7 @@ fn zirReify( | ... | @@ -21535,7 +21565,7 @@ fn zirReify( |
| 21535 | ip, | 21565 | ip, |
| 21536 | try ip.getOrPutString(gpa, "return_type"), | 21566 | try ip.getOrPutString(gpa, "return_type"), |
| 21537 | ).?); | 21567 | ).?); |
| 21538 | const params_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( | 21568 | const params_slice_val = try Value.fromInterned(union_val.val).fieldValue(mod, struct_type.nameIndex( |
| 21539 | ip, | 21569 | ip, |
| 21540 | try ip.getOrPutString(gpa, "params"), | 21570 | try ip.getOrPutString(gpa, "params"), |
| 21541 | ).?); | 21571 | ).?); |
| ... | @@ -21554,12 +21584,16 @@ fn zirReify( | ... | @@ -21554,12 +21584,16 @@ fn zirReify( |
| 21554 | const return_type = return_type_val.optionalValue(mod) orelse | 21584 | const return_type = return_type_val.optionalValue(mod) orelse |
| 21555 | return sema.fail(block, src, "Type.Fn.return_type must be non-null for @Type", .{}); | 21585 | return sema.fail(block, src, "Type.Fn.return_type must be non-null for @Type", .{}); |
| 21556 | 21586 | ||
| 21557 | const args_len = try sema.usizeCast(block, src, params_val.sliceLen(mod)); | 21587 | const params_val = try sema.derefSliceAsArray(block, operand_src, params_slice_val, .{ |
| 21588 | .needed_comptime_reason = "function parameters must be comptime-known", | ||
| 21589 | }); | ||
| 21590 | |||
| 21591 | const args_len = try sema.usizeCast(block, src, params_val.typeOf(mod).arrayLen(mod)); | ||
| 21558 | const param_types = try sema.arena.alloc(InternPool.Index, args_len); | 21592 | const param_types = try sema.arena.alloc(InternPool.Index, args_len); |
| 21559 | 21593 | ||
| 21560 | var noalias_bits: u32 = 0; | 21594 | var noalias_bits: u32 = 0; |
| 21561 | for (param_types, 0..) |*param_type, i| { | 21595 | for (param_types, 0..) |*param_type, i| { |
| 21562 | const elem_val = (try params_val.maybeElemValueFull(sema, mod, i)).?; | 21596 | const elem_val = try params_val.elemValue(mod, i); |
| 21563 | const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern())); | 21597 | const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern())); |
| 21564 | const param_is_generic_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex( | 21598 | const param_is_generic_val = try elem_val.fieldValue(mod, elem_struct_type.nameIndex( |
| 21565 | ip, | 21599 | ip, |
| ... | @@ -21620,7 +21654,7 @@ fn reifyEnum( | ... | @@ -21620,7 +21654,7 @@ fn reifyEnum( |
| 21620 | 21654 | ||
| 21621 | // This logic must stay in sync with the structure of `std.builtin.Type.Enum` - search for `fieldValue`. | 21655 | // This logic must stay in sync with the structure of `std.builtin.Type.Enum` - search for `fieldValue`. |
| 21622 | 21656 | ||
| 21623 | const fields_len: u32 = @intCast(fields_val.sliceLen(mod)); | 21657 | const fields_len: u32 = @intCast(fields_val.typeOf(mod).arrayLen(mod)); |
| 21624 | 21658 | ||
| 21625 | // The validation work here is non-trivial, and it's possible the type already exists. | 21659 | // The validation work here is non-trivial, and it's possible the type already exists. |
| 21626 | // So in this first pass, let's just construct a hash to optimize for this case. If the | 21660 | // So in this first pass, let's just construct a hash to optimize for this case. If the |
| ... | @@ -21634,7 +21668,7 @@ fn reifyEnum( | ... | @@ -21634,7 +21668,7 @@ fn reifyEnum( |
| 21634 | std.hash.autoHash(&hasher, fields_len); | 21668 | std.hash.autoHash(&hasher, fields_len); |
| 21635 | 21669 | ||
| 21636 | for (0..fields_len) |field_idx| { | 21670 | for (0..fields_len) |field_idx| { |
| 21637 | const field_info = (try fields_val.maybeElemValueFull(sema, mod, field_idx)).?; | 21671 | const field_info = try fields_val.elemValue(mod, field_idx); |
| 21638 | 21672 | ||
| 21639 | const field_name_val = try field_info.fieldValue(mod, 0); | 21673 | const field_name_val = try field_info.fieldValue(mod, 0); |
| 21640 | const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 1)); | 21674 | const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 1)); |
| ... | @@ -21668,10 +21702,14 @@ fn reifyEnum( | ... | @@ -21668,10 +21702,14 @@ fn reifyEnum( |
| 21668 | return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{}); | 21702 | return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{}); |
| 21669 | } | 21703 | } |
| 21670 | 21704 | ||
| 21671 | const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{ | 21705 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( |
| 21672 | .ty = Type.type, | 21706 | block, |
| 21673 | .val = Value.fromInterned(wip_ty.index), | 21707 | src, |
| 21674 | }, name_strategy, "enum", inst); | 21708 | Value.fromInterned(wip_ty.index), |
| 21709 | name_strategy, | ||
| 21710 | "enum", | ||
| 21711 | inst, | ||
| 21712 | ); | ||
| 21675 | mod.declPtr(new_decl_index).owns_tv = true; | 21713 | mod.declPtr(new_decl_index).owns_tv = true; |
| 21676 | errdefer mod.abortAnonDecl(new_decl_index); | 21714 | errdefer mod.abortAnonDecl(new_decl_index); |
| 21677 | 21715 | ||
| ... | @@ -21679,7 +21717,7 @@ fn reifyEnum( | ... | @@ -21679,7 +21717,7 @@ fn reifyEnum( |
| 21679 | wip_ty.setTagTy(ip, tag_ty.toIntern()); | 21717 | wip_ty.setTagTy(ip, tag_ty.toIntern()); |
| 21680 | 21718 | ||
| 21681 | for (0..fields_len) |field_idx| { | 21719 | for (0..fields_len) |field_idx| { |
| 21682 | const field_info = (try fields_val.maybeElemValueFull(sema, mod, field_idx)).?; | 21720 | const field_info = try fields_val.elemValue(mod, field_idx); |
| 21683 | 21721 | ||
| 21684 | const field_name_val = try field_info.fieldValue(mod, 0); | 21722 | const field_name_val = try field_info.fieldValue(mod, 0); |
| 21685 | const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 1)); | 21723 | const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(mod, 1)); |
| ... | @@ -21691,7 +21729,7 @@ fn reifyEnum( | ... | @@ -21691,7 +21729,7 @@ fn reifyEnum( |
| 21691 | // TODO: better source location | 21729 | // TODO: better source location |
| 21692 | return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{ | 21730 | return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{ |
| 21693 | field_name.fmt(ip), | 21731 | field_name.fmt(ip), |
| 21694 | field_value_val.fmtValue(Type.comptime_int, mod), | 21732 | field_value_val.fmtValue(mod), |
| 21695 | tag_ty.fmt(mod), | 21733 | tag_ty.fmt(mod), |
| 21696 | }); | 21734 | }); |
| 21697 | } | 21735 | } |
| ... | @@ -21707,7 +21745,7 @@ fn reifyEnum( | ... | @@ -21707,7 +21745,7 @@ fn reifyEnum( |
| 21707 | break :msg msg; | 21745 | break :msg msg; |
| 21708 | }, | 21746 | }, |
| 21709 | .value => msg: { | 21747 | .value => msg: { |
| 21710 | const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{field_value_val.fmtValue(Type.comptime_int, mod)}); | 21748 | const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{field_value_val.fmtValue(mod)}); |
| 21711 | errdefer msg.destroy(gpa); | 21749 | errdefer msg.destroy(gpa); |
| 21712 | _ = conflict.prev_field_idx; // TODO: this note is incorrect | 21750 | _ = conflict.prev_field_idx; // TODO: this note is incorrect |
| 21713 | try sema.errNote(block, src, msg, "other enum tag value here", .{}); | 21751 | try sema.errNote(block, src, msg, "other enum tag value here", .{}); |
| ... | @@ -21741,7 +21779,7 @@ fn reifyUnion( | ... | @@ -21741,7 +21779,7 @@ fn reifyUnion( |
| 21741 | 21779 | ||
| 21742 | // This logic must stay in sync with the structure of `std.builtin.Type.Union` - search for `fieldValue`. | 21780 | // This logic must stay in sync with the structure of `std.builtin.Type.Union` - search for `fieldValue`. |
| 21743 | 21781 | ||
| 21744 | const fields_len: u32 = @intCast(fields_val.sliceLen(mod)); | 21782 | const fields_len: u32 = @intCast(fields_val.typeOf(mod).arrayLen(mod)); |
| 21745 | 21783 | ||
| 21746 | // The validation work here is non-trivial, and it's possible the type already exists. | 21784 | // The validation work here is non-trivial, and it's possible the type already exists. |
| 21747 | // So in this first pass, let's just construct a hash to optimize for this case. If the | 21785 | // So in this first pass, let's just construct a hash to optimize for this case. If the |
| ... | @@ -21757,7 +21795,7 @@ fn reifyUnion( | ... | @@ -21757,7 +21795,7 @@ fn reifyUnion( |
| 21757 | var any_aligns = false; | 21795 | var any_aligns = false; |
| 21758 | 21796 | ||
| 21759 | for (0..fields_len) |field_idx| { | 21797 | for (0..fields_len) |field_idx| { |
| 21760 | const field_info = (try fields_val.maybeElemValueFull(sema, mod, field_idx)).?; | 21798 | const field_info = try fields_val.elemValue(mod, field_idx); |
| 21761 | 21799 | ||
| 21762 | const field_name_val = try field_info.fieldValue(mod, 0); | 21800 | const field_name_val = try field_info.fieldValue(mod, 0); |
| 21763 | const field_type_val = try field_info.fieldValue(mod, 1); | 21801 | const field_type_val = try field_info.fieldValue(mod, 1); |
| ... | @@ -21811,10 +21849,14 @@ fn reifyUnion( | ... | @@ -21811,10 +21849,14 @@ fn reifyUnion( |
| 21811 | }; | 21849 | }; |
| 21812 | errdefer wip_ty.cancel(ip); | 21850 | errdefer wip_ty.cancel(ip); |
| 21813 | 21851 | ||
| 21814 | const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{ | 21852 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( |
| 21815 | .ty = Type.type, | 21853 | block, |
| 21816 | .val = Value.fromInterned(wip_ty.index), | 21854 | src, |
| 21817 | }, name_strategy, "union", inst); | 21855 | Value.fromInterned(wip_ty.index), |
| 21856 | name_strategy, | ||
| 21857 | "union", | ||
| 21858 | inst, | ||
| 21859 | ); | ||
| 21818 | mod.declPtr(new_decl_index).owns_tv = true; | 21860 | mod.declPtr(new_decl_index).owns_tv = true; |
| 21819 | errdefer mod.abortAnonDecl(new_decl_index); | 21861 | errdefer mod.abortAnonDecl(new_decl_index); |
| 21820 | 21862 | ||
| ... | @@ -21833,7 +21875,7 @@ fn reifyUnion( | ... | @@ -21833,7 +21875,7 @@ fn reifyUnion( |
| 21833 | var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len); | 21875 | var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len); |
| 21834 | 21876 | ||
| 21835 | for (field_types, 0..) |*field_ty, field_idx| { | 21877 | for (field_types, 0..) |*field_ty, field_idx| { |
| 21836 | const field_info = (try fields_val.maybeElemValueFull(sema, mod, field_idx)).?; | 21878 | const field_info = try fields_val.elemValue(mod, field_idx); |
| 21837 | 21879 | ||
| 21838 | const field_name_val = try field_info.fieldValue(mod, 0); | 21880 | const field_name_val = try field_info.fieldValue(mod, 0); |
| 21839 | const field_type_val = try field_info.fieldValue(mod, 1); | 21881 | const field_type_val = try field_info.fieldValue(mod, 1); |
| ... | @@ -21885,7 +21927,7 @@ fn reifyUnion( | ... | @@ -21885,7 +21927,7 @@ fn reifyUnion( |
| 21885 | try field_names.ensureTotalCapacity(sema.arena, fields_len); | 21927 | try field_names.ensureTotalCapacity(sema.arena, fields_len); |
| 21886 | 21928 | ||
| 21887 | for (field_types, 0..) |*field_ty, field_idx| { | 21929 | for (field_types, 0..) |*field_ty, field_idx| { |
| 21888 | const field_info = (try fields_val.maybeElemValueFull(sema, mod, field_idx)).?; | 21930 | const field_info = try fields_val.elemValue(mod, field_idx); |
| 21889 | 21931 | ||
| 21890 | const field_name_val = try field_info.fieldValue(mod, 0); | 21932 | const field_name_val = try field_info.fieldValue(mod, 0); |
| 21891 | const field_type_val = try field_info.fieldValue(mod, 1); | 21933 | const field_type_val = try field_info.fieldValue(mod, 1); |
| ... | @@ -21979,7 +22021,7 @@ fn reifyStruct( | ... | @@ -21979,7 +22021,7 @@ fn reifyStruct( |
| 21979 | 22021 | ||
| 21980 | // This logic must stay in sync with the structure of `std.builtin.Type.Struct` - search for `fieldValue`. | 22022 | // This logic must stay in sync with the structure of `std.builtin.Type.Struct` - search for `fieldValue`. |
| 21981 | 22023 | ||
| 21982 | const fields_len: u32 = @intCast(fields_val.sliceLen(mod)); | 22024 | const fields_len: u32 = @intCast(fields_val.typeOf(mod).arrayLen(mod)); |
| 21983 | 22025 | ||
| 21984 | // The validation work here is non-trivial, and it's possible the type already exists. | 22026 | // The validation work here is non-trivial, and it's possible the type already exists. |
| 21985 | // So in this first pass, let's just construct a hash to optimize for this case. If the | 22027 | // So in this first pass, let's just construct a hash to optimize for this case. If the |
| ... | @@ -21998,7 +22040,7 @@ fn reifyStruct( | ... | @@ -21998,7 +22040,7 @@ fn reifyStruct( |
| 21998 | var any_aligned_fields = false; | 22040 | var any_aligned_fields = false; |
| 21999 | 22041 | ||
| 22000 | for (0..fields_len) |field_idx| { | 22042 | for (0..fields_len) |field_idx| { |
| 22001 | const field_info = (try fields_val.maybeElemValueFull(sema, mod, field_idx)).?; | 22043 | const field_info = try fields_val.elemValue(mod, field_idx); |
| 22002 | 22044 | ||
| 22003 | const field_name_val = try field_info.fieldValue(mod, 0); | 22045 | const field_name_val = try field_info.fieldValue(mod, 0); |
| 22004 | const field_type_val = try field_info.fieldValue(mod, 1); | 22046 | const field_type_val = try field_info.fieldValue(mod, 1); |
| ... | @@ -22066,17 +22108,21 @@ fn reifyStruct( | ... | @@ -22066,17 +22108,21 @@ fn reifyStruct( |
| 22066 | .auto => {}, | 22108 | .auto => {}, |
| 22067 | }; | 22109 | }; |
| 22068 | 22110 | ||
| 22069 | const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{ | 22111 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( |
| 22070 | .ty = Type.type, | 22112 | block, |
| 22071 | .val = Value.fromInterned(wip_ty.index), | 22113 | src, |
| 22072 | }, name_strategy, "struct", inst); | 22114 | Value.fromInterned(wip_ty.index), |
| 22115 | name_strategy, | ||
| 22116 | "struct", | ||
| 22117 | inst, | ||
| 22118 | ); | ||
| 22073 | mod.declPtr(new_decl_index).owns_tv = true; | 22119 | mod.declPtr(new_decl_index).owns_tv = true; |
| 22074 | errdefer mod.abortAnonDecl(new_decl_index); | 22120 | errdefer mod.abortAnonDecl(new_decl_index); |
| 22075 | 22121 | ||
| 22076 | const struct_type = ip.loadStructType(wip_ty.index); | 22122 | const struct_type = ip.loadStructType(wip_ty.index); |
| 22077 | 22123 | ||
| 22078 | for (0..fields_len) |field_idx| { | 22124 | for (0..fields_len) |field_idx| { |
| 22079 | const field_info = (try fields_val.maybeElemValueFull(sema, mod, field_idx)).?; | 22125 | const field_info = try fields_val.elemValue(mod, field_idx); |
| 22080 | 22126 | ||
| 22081 | const field_name_val = try field_info.fieldValue(mod, 0); | 22127 | const field_name_val = try field_info.fieldValue(mod, 0); |
| 22082 | const field_type_val = try field_info.fieldValue(mod, 1); | 22128 | const field_type_val = try field_info.fieldValue(mod, 1); |
| ... | @@ -22837,12 +22883,12 @@ fn ptrCastFull( | ... | @@ -22837,12 +22883,12 @@ fn ptrCastFull( |
| 22837 | return sema.failWithOwnedErrorMsg(block, msg: { | 22883 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 22838 | const msg = if (src_info.sentinel == .none) blk: { | 22884 | const msg = if (src_info.sentinel == .none) blk: { |
| 22839 | break :blk try sema.errMsg(block, src, "destination pointer requires '{}' sentinel", .{ | 22885 | break :blk try sema.errMsg(block, src, "destination pointer requires '{}' sentinel", .{ |
| 22840 | Value.fromInterned(dest_info.sentinel).fmtValue(Type.fromInterned(dest_info.child), mod), | 22886 | Value.fromInterned(dest_info.sentinel).fmtValue(mod), |
| 22841 | }); | 22887 | }); |
| 22842 | } else blk: { | 22888 | } else blk: { |
| 22843 | break :blk try sema.errMsg(block, src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{ | 22889 | break :blk try sema.errMsg(block, src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{ |
| 22844 | Value.fromInterned(src_info.sentinel).fmtValue(Type.fromInterned(src_info.child), mod), | 22890 | Value.fromInterned(src_info.sentinel).fmtValue(mod), |
| 22845 | Value.fromInterned(dest_info.sentinel).fmtValue(Type.fromInterned(dest_info.child), mod), | 22891 | Value.fromInterned(dest_info.sentinel).fmtValue(mod), |
| 22846 | }); | 22892 | }); |
| 22847 | }; | 22893 | }; |
| 22848 | errdefer msg.destroy(sema.gpa); | 22894 | errdefer msg.destroy(sema.gpa); |
| ... | @@ -23216,7 +23262,8 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -23216,7 +23262,8 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23216 | const elems = try sema.arena.alloc(InternPool.Index, operand_ty.vectorLen(mod)); | 23262 | const elems = try sema.arena.alloc(InternPool.Index, operand_ty.vectorLen(mod)); |
| 23217 | for (elems, 0..) |*elem, i| { | 23263 | for (elems, 0..) |*elem, i| { |
| 23218 | const elem_val = try val.elemValue(mod, i); | 23264 | const elem_val = try val.elemValue(mod, i); |
| 23219 | elem.* = try (try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, mod)).intern(dest_scalar_ty, mod); | 23265 | const uncoerced_elem = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, mod); |
| 23266 | elem.* = (try mod.getCoerced(uncoerced_elem, dest_scalar_ty)).toIntern(); | ||
| 23220 | } | 23267 | } |
| 23221 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 23268 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ |
| 23222 | .ty = dest_ty.toIntern(), | 23269 | .ty = dest_ty.toIntern(), |
| ... | @@ -23330,7 +23377,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -23330,7 +23377,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 23330 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); | 23377 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 23331 | for (elems, 0..) |*elem, i| { | 23378 | for (elems, 0..) |*elem, i| { |
| 23332 | const elem_val = try val.elemValue(mod, i); | 23379 | const elem_val = try val.elemValue(mod, i); |
| 23333 | elem.* = try (try elem_val.byteSwap(scalar_ty, mod, sema.arena)).intern(scalar_ty, mod); | 23380 | elem.* = (try elem_val.byteSwap(scalar_ty, mod, sema.arena)).toIntern(); |
| 23334 | } | 23381 | } |
| 23335 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 23382 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ |
| 23336 | .ty = operand_ty.toIntern(), | 23383 | .ty = operand_ty.toIntern(), |
| ... | @@ -23378,7 +23425,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -23378,7 +23425,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 23378 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); | 23425 | const elems = try sema.arena.alloc(InternPool.Index, vec_len); |
| 23379 | for (elems, 0..) |*elem, i| { | 23426 | for (elems, 0..) |*elem, i| { |
| 23380 | const elem_val = try val.elemValue(mod, i); | 23427 | const elem_val = try val.elemValue(mod, i); |
| 23381 | elem.* = try (try elem_val.bitReverse(scalar_ty, mod, sema.arena)).intern(scalar_ty, mod); | 23428 | elem.* = (try elem_val.bitReverse(scalar_ty, mod, sema.arena)).toIntern(); |
| 23382 | } | 23429 | } |
| 23383 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 23430 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ |
| 23384 | .ty = operand_ty.toIntern(), | 23431 | .ty = operand_ty.toIntern(), |
| ... | @@ -23896,11 +23943,9 @@ fn resolveExportOptions( | ... | @@ -23896,11 +23943,9 @@ fn resolveExportOptions( |
| 23896 | const visibility_src = sema.maybeOptionsSrc(block, src, "visibility"); | 23943 | const visibility_src = sema.maybeOptionsSrc(block, src, "visibility"); |
| 23897 | 23944 | ||
| 23898 | const name_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name"), name_src); | 23945 | const name_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name"), name_src); |
| 23899 | const name_val = try sema.resolveConstDefinedValue(block, name_src, name_operand, .{ | 23946 | const name = try sema.toConstString(block, name_src, name_operand, .{ |
| 23900 | .needed_comptime_reason = "name of exported value must be comptime-known", | 23947 | .needed_comptime_reason = "name of exported value must be comptime-known", |
| 23901 | }); | 23948 | }); |
| 23902 | const name_ty = Type.slice_const_u8; | ||
| 23903 | const name = try name_val.toAllocatedBytes(name_ty, sema.arena, mod); | ||
| 23904 | 23949 | ||
| 23905 | const linkage_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "linkage"), linkage_src); | 23950 | const linkage_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "linkage"), linkage_src); |
| 23906 | const linkage_val = try sema.resolveConstDefinedValue(block, linkage_src, linkage_operand, .{ | 23951 | const linkage_val = try sema.resolveConstDefinedValue(block, linkage_src, linkage_operand, .{ |
| ... | @@ -23912,9 +23957,10 @@ fn resolveExportOptions( | ... | @@ -23912,9 +23957,10 @@ fn resolveExportOptions( |
| 23912 | const section_opt_val = try sema.resolveConstDefinedValue(block, section_src, section_operand, .{ | 23957 | const section_opt_val = try sema.resolveConstDefinedValue(block, section_src, section_operand, .{ |
| 23913 | .needed_comptime_reason = "linksection of exported value must be comptime-known", | 23958 | .needed_comptime_reason = "linksection of exported value must be comptime-known", |
| 23914 | }); | 23959 | }); |
| 23915 | const section_ty = Type.slice_const_u8; | ||
| 23916 | const section = if (section_opt_val.optionalValue(mod)) |section_val| | 23960 | const section = if (section_opt_val.optionalValue(mod)) |section_val| |
| 23917 | try section_val.toAllocatedBytes(section_ty, sema.arena, mod) | 23961 | try sema.toConstString(block, section_src, Air.internedToRef(section_val.toIntern()), .{ |
| 23962 | .needed_comptime_reason = "linksection of exported value must be comptime-known", | ||
| 23963 | }) | ||
| 23918 | else | 23964 | else |
| 23919 | null; | 23965 | null; |
| 23920 | 23966 | ||
| ... | @@ -24311,7 +24357,7 @@ fn analyzeShuffle( | ... | @@ -24311,7 +24357,7 @@ fn analyzeShuffle( |
| 24311 | } | 24357 | } |
| 24312 | const int = mask_elem_val.toSignedInt(mod); | 24358 | const int = mask_elem_val.toSignedInt(mod); |
| 24313 | const unsigned: u32 = @intCast(if (int >= 0) int else ~int); | 24359 | const unsigned: u32 = @intCast(if (int >= 0) int else ~int); |
| 24314 | values[i] = try (try (if (int >= 0) a_val else b_val).elemValue(mod, unsigned)).intern(elem_ty, mod); | 24360 | values[i] = (try (if (int >= 0) a_val else b_val).elemValue(mod, unsigned)).toIntern(); |
| 24315 | } | 24361 | } |
| 24316 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 24362 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ |
| 24317 | .ty = res_ty.toIntern(), | 24363 | .ty = res_ty.toIntern(), |
| ... | @@ -24417,7 +24463,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C | ... | @@ -24417,7 +24463,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C |
| 24417 | for (elems, 0..) |*elem, i| { | 24463 | for (elems, 0..) |*elem, i| { |
| 24418 | const pred_elem_val = try pred_val.elemValue(mod, i); | 24464 | const pred_elem_val = try pred_val.elemValue(mod, i); |
| 24419 | const should_choose_a = pred_elem_val.toBool(); | 24465 | const should_choose_a = pred_elem_val.toBool(); |
| 24420 | elem.* = try (try (if (should_choose_a) a_val else b_val).elemValue(mod, i)).intern(elem_ty, mod); | 24466 | elem.* = (try (if (should_choose_a) a_val else b_val).elemValue(mod, i)).toIntern(); |
| 24421 | } | 24467 | } |
| 24422 | 24468 | ||
| 24423 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ | 24469 | return Air.internedToRef((try mod.intern(.{ .aggregate = .{ |
| ... | @@ -25239,10 +25285,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -25239,10 +25285,10 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 25239 | const msg = try sema.errMsg(block, src, "non-matching @memcpy lengths", .{}); | 25285 | const msg = try sema.errMsg(block, src, "non-matching @memcpy lengths", .{}); |
| 25240 | errdefer msg.destroy(sema.gpa); | 25286 | errdefer msg.destroy(sema.gpa); |
| 25241 | try sema.errNote(block, dest_src, msg, "length {} here", .{ | 25287 | try sema.errNote(block, dest_src, msg, "length {} here", .{ |
| 25242 | dest_len_val.fmtValue(Type.usize, sema.mod), | 25288 | dest_len_val.fmtValue(sema.mod), |
| 25243 | }); | 25289 | }); |
| 25244 | try sema.errNote(block, src_src, msg, "length {} here", .{ | 25290 | try sema.errNote(block, src_src, msg, "length {} here", .{ |
| 25245 | src_len_val.fmtValue(Type.usize, sema.mod), | 25291 | src_len_val.fmtValue(sema.mod), |
| 25246 | }); | 25292 | }); |
| 25247 | break :msg msg; | 25293 | break :msg msg; |
| 25248 | }; | 25294 | }; |
| ... | @@ -25777,7 +25823,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -25777,7 +25823,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 25777 | } else if (extra.data.bits.has_ret_ty_ref) blk: { | 25823 | } else if (extra.data.bits.has_ret_ty_ref) blk: { |
| 25778 | const ret_ty_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); | 25824 | const ret_ty_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); |
| 25779 | extra_index += 1; | 25825 | extra_index += 1; |
| 25780 | const ret_ty_tv = sema.resolveInstConst(block, ret_src, ret_ty_ref, .{ | 25826 | const ret_ty_val = sema.resolveInstConst(block, ret_src, ret_ty_ref, .{ |
| 25781 | .needed_comptime_reason = "return type must be comptime-known", | 25827 | .needed_comptime_reason = "return type must be comptime-known", |
| 25782 | }) catch |err| switch (err) { | 25828 | }) catch |err| switch (err) { |
| 25783 | error.GenericPoison => { | 25829 | error.GenericPoison => { |
| ... | @@ -25785,8 +25831,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -25785,8 +25831,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 25785 | }, | 25831 | }, |
| 25786 | else => |e| return e, | 25832 | else => |e| return e, |
| 25787 | }; | 25833 | }; |
| 25788 | const ty = ret_ty_tv.val.toType(); | 25834 | break :blk ret_ty_val.toType(); |
| 25789 | break :blk ty; | ||
| 25790 | } else Type.void; | 25835 | } else Type.void; |
| 25791 | 25836 | ||
| 25792 | const noalias_bits: u32 = if (extra.data.bits.has_any_noalias) blk: { | 25837 | const noalias_bits: u32 = if (extra.data.bits.has_any_noalias) blk: { |
| ... | @@ -26032,10 +26077,9 @@ fn resolveExternOptions( | ... | @@ -26032,10 +26077,9 @@ fn resolveExternOptions( |
| 26032 | const thread_local_src = sema.maybeOptionsSrc(block, src, "thread_local"); | 26077 | const thread_local_src = sema.maybeOptionsSrc(block, src, "thread_local"); |
| 26033 | 26078 | ||
| 26034 | const name_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name"), name_src); | 26079 | const name_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name"), name_src); |
| 26035 | const name_val = try sema.resolveConstDefinedValue(block, name_src, name_ref, .{ | 26080 | const name = try sema.toConstString(block, name_src, name_ref, .{ |
| 26036 | .needed_comptime_reason = "name of the extern symbol must be comptime-known", | 26081 | .needed_comptime_reason = "name of the extern symbol must be comptime-known", |
| 26037 | }); | 26082 | }); |
| 26038 | const name = try name_val.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod); | ||
| 26039 | 26083 | ||
| 26040 | const library_name_inst = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "library_name"), library_src); | 26084 | const library_name_inst = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "library_name"), library_src); |
| 26041 | const library_name_val = try sema.resolveConstDefinedValue(block, library_src, library_name_inst, .{ | 26085 | const library_name_val = try sema.resolveConstDefinedValue(block, library_src, library_name_inst, .{ |
| ... | @@ -26054,7 +26098,9 @@ fn resolveExternOptions( | ... | @@ -26054,7 +26098,9 @@ fn resolveExternOptions( |
| 26054 | }); | 26098 | }); |
| 26055 | 26099 | ||
| 26056 | const library_name = if (library_name_val.optionalValue(mod)) |library_name_payload| library_name: { | 26100 | const library_name = if (library_name_val.optionalValue(mod)) |library_name_payload| library_name: { |
| 26057 | const library_name = try library_name_payload.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod); | 26101 | const library_name = try sema.toConstString(block, library_src, Air.internedToRef(library_name_payload.toIntern()), .{ |
| 26102 | .needed_comptime_reason = "library in which extern symbol is must be comptime-known", | ||
| 26103 | }); | ||
| 26058 | if (library_name.len == 0) { | 26104 | if (library_name.len == 0) { |
| 26059 | return sema.fail(block, library_src, "library name cannot be empty", .{}); | 26105 | return sema.fail(block, library_src, "library name cannot be empty", .{}); |
| 26060 | } | 26106 | } |
| ... | @@ -26120,9 +26166,10 @@ fn zirBuiltinExtern( | ... | @@ -26120,9 +26166,10 @@ fn zirBuiltinExtern( |
| 26120 | const new_decl_index = try mod.allocateNewDecl(sema.owner_decl.src_namespace, sema.owner_decl.src_node); | 26166 | const new_decl_index = try mod.allocateNewDecl(sema.owner_decl.src_namespace, sema.owner_decl.src_node); |
| 26121 | errdefer mod.destroyDecl(new_decl_index); | 26167 | errdefer mod.destroyDecl(new_decl_index); |
| 26122 | const new_decl = mod.declPtr(new_decl_index); | 26168 | const new_decl = mod.declPtr(new_decl_index); |
| 26123 | try mod.initNewAnonDecl(new_decl_index, sema.owner_decl.src_line, .{ | 26169 | try mod.initNewAnonDecl( |
| 26124 | .ty = Type.fromInterned(ptr_info.child), | 26170 | new_decl_index, |
| 26125 | .val = Value.fromInterned( | 26171 | sema.owner_decl.src_line, |
| 26172 | Value.fromInterned( | ||
| 26126 | if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn) | 26173 | if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn) |
| 26127 | try ip.getExternFunc(sema.gpa, .{ | 26174 | try ip.getExternFunc(sema.gpa, .{ |
| 26128 | .ty = ptr_info.child, | 26175 | .ty = ptr_info.child, |
| ... | @@ -26141,7 +26188,8 @@ fn zirBuiltinExtern( | ... | @@ -26141,7 +26188,8 @@ fn zirBuiltinExtern( |
| 26141 | .is_weak_linkage = options.linkage == .weak, | 26188 | .is_weak_linkage = options.linkage == .weak, |
| 26142 | } }), | 26189 | } }), |
| 26143 | ), | 26190 | ), |
| 26144 | }, options.name); | 26191 | options.name, |
| 26192 | ); | ||
| 26145 | new_decl.owns_tv = true; | 26193 | new_decl.owns_tv = true; |
| 26146 | // Note that this will queue the anon decl for codegen, so that the backend can | 26194 | // Note that this will queue the anon decl for codegen, so that the backend can |
| 26147 | // correctly handle the extern, including duplicate detection. | 26195 | // correctly handle the extern, including duplicate detection. |
| ... | @@ -26641,13 +26689,12 @@ fn prepareSimplePanic(sema: *Sema, block: *Block) !void { | ... | @@ -26641,13 +26689,12 @@ fn prepareSimplePanic(sema: *Sema, block: *Block) !void { |
| 26641 | // decl_index may be an alias; we must find the decl that actually | 26689 | // decl_index may be an alias; we must find the decl that actually |
| 26642 | // owns the function. | 26690 | // owns the function. |
| 26643 | try sema.ensureDeclAnalyzed(decl_index); | 26691 | try sema.ensureDeclAnalyzed(decl_index); |
| 26644 | const tv = try mod.declPtr(decl_index).typedValue(); | 26692 | const fn_val = try mod.declPtr(decl_index).valueOrFail(); |
| 26645 | try sema.declareDependency(.{ .decl_val = decl_index }); | 26693 | try sema.declareDependency(.{ .decl_val = decl_index }); |
| 26646 | assert(tv.ty.zigTypeTag(mod) == .Fn); | 26694 | assert(fn_val.typeOf(mod).zigTypeTag(mod) == .Fn); |
| 26647 | assert(try sema.fnHasRuntimeBits(tv.ty)); | 26695 | assert(try sema.fnHasRuntimeBits(fn_val.typeOf(mod))); |
| 26648 | const func_index = tv.val.toIntern(); | 26696 | try mod.ensureFuncBodyAnalysisQueued(fn_val.toIntern()); |
| 26649 | try mod.ensureFuncBodyAnalysisQueued(func_index); | 26697 | mod.panic_func_index = fn_val.toIntern(); |
| 26650 | mod.panic_func_index = func_index; | ||
| 26651 | } | 26698 | } |
| 26652 | 26699 | ||
| 26653 | if (mod.null_stack_trace == .none) { | 26700 | if (mod.null_stack_trace == .none) { |
| ... | @@ -27789,7 +27836,7 @@ fn structFieldPtrByIndex( | ... | @@ -27789,7 +27836,7 @@ fn structFieldPtrByIndex( |
| 27789 | const val = try mod.intern(.{ .ptr = .{ | 27836 | const val = try mod.intern(.{ .ptr = .{ |
| 27790 | .ty = ptr_field_ty.toIntern(), | 27837 | .ty = ptr_field_ty.toIntern(), |
| 27791 | .addr = .{ .field = .{ | 27838 | .addr = .{ .field = .{ |
| 27792 | .base = try struct_ptr_val.intern(struct_ptr_ty, mod), | 27839 | .base = struct_ptr_val.toIntern(), |
| 27793 | .index = field_index, | 27840 | .index = field_index, |
| 27794 | } }, | 27841 | } }, |
| 27795 | } }); | 27842 | } }); |
| ... | @@ -28568,7 +28615,7 @@ fn elemValSlice( | ... | @@ -28568,7 +28615,7 @@ fn elemValSlice( |
| 28568 | 28615 | ||
| 28569 | if (maybe_slice_val) |slice_val| { | 28616 | if (maybe_slice_val) |slice_val| { |
| 28570 | runtime_src = elem_index_src; | 28617 | runtime_src = elem_index_src; |
| 28571 | const slice_len = slice_val.sliceLen(mod); | 28618 | const slice_len = try slice_val.sliceLen(sema); |
| 28572 | const slice_len_s = slice_len + @intFromBool(slice_sent); | 28619 | const slice_len_s = slice_len + @intFromBool(slice_sent); |
| 28573 | if (slice_len_s == 0) { | 28620 | if (slice_len_s == 0) { |
| 28574 | return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{}); | 28621 | return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{}); |
| ... | @@ -28593,7 +28640,7 @@ fn elemValSlice( | ... | @@ -28593,7 +28640,7 @@ fn elemValSlice( |
| 28593 | try sema.requireRuntimeBlock(block, src, runtime_src); | 28640 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 28594 | if (oob_safety and block.wantSafety()) { | 28641 | if (oob_safety and block.wantSafety()) { |
| 28595 | const len_inst = if (maybe_slice_val) |slice_val| | 28642 | const len_inst = if (maybe_slice_val) |slice_val| |
| 28596 | try mod.intRef(Type.usize, slice_val.sliceLen(mod)) | 28643 | try mod.intRef(Type.usize, try slice_val.sliceLen(sema)) |
| 28597 | else | 28644 | else |
| 28598 | try block.addTyOp(.slice_len, Type.usize, slice); | 28645 | try block.addTyOp(.slice_len, Type.usize, slice); |
| 28599 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; | 28646 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; |
| ... | @@ -28630,7 +28677,7 @@ fn elemPtrSlice( | ... | @@ -28630,7 +28677,7 @@ fn elemPtrSlice( |
| 28630 | if (slice_val.isUndef(mod)) { | 28677 | if (slice_val.isUndef(mod)) { |
| 28631 | return mod.undefRef(elem_ptr_ty); | 28678 | return mod.undefRef(elem_ptr_ty); |
| 28632 | } | 28679 | } |
| 28633 | const slice_len = slice_val.sliceLen(mod); | 28680 | const slice_len = try slice_val.sliceLen(sema); |
| 28634 | const slice_len_s = slice_len + @intFromBool(slice_sent); | 28681 | const slice_len_s = slice_len + @intFromBool(slice_sent); |
| 28635 | if (slice_len_s == 0) { | 28682 | if (slice_len_s == 0) { |
| 28636 | return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{}); | 28683 | return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{}); |
| ... | @@ -28653,7 +28700,7 @@ fn elemPtrSlice( | ... | @@ -28653,7 +28700,7 @@ fn elemPtrSlice( |
| 28653 | const len_inst = len: { | 28700 | const len_inst = len: { |
| 28654 | if (maybe_undef_slice_val) |slice_val| | 28701 | if (maybe_undef_slice_val) |slice_val| |
| 28655 | if (!slice_val.isUndef(mod)) | 28702 | if (!slice_val.isUndef(mod)) |
| 28656 | break :len try mod.intRef(Type.usize, slice_val.sliceLen(mod)); | 28703 | break :len try mod.intRef(Type.usize, try slice_val.sliceLen(sema)); |
| 28657 | break :len try block.addTyOp(.slice_len, Type.usize, slice); | 28704 | break :len try block.addTyOp(.slice_len, Type.usize, slice); |
| 28658 | }; | 28705 | }; |
| 28659 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; | 28706 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; |
| ... | @@ -29115,7 +29162,7 @@ fn coerceExtra( | ... | @@ -29115,7 +29162,7 @@ fn coerceExtra( |
| 29115 | // comptime-known integer to other number | 29162 | // comptime-known integer to other number |
| 29116 | if (!(try sema.intFitsInType(val, dest_ty, null))) { | 29163 | if (!(try sema.intFitsInType(val, dest_ty, null))) { |
| 29117 | if (!opts.report_err) return error.NotCoercible; | 29164 | if (!opts.report_err) return error.NotCoercible; |
| 29118 | return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(mod), val.fmtValue(inst_ty, mod) }); | 29165 | return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(mod), val.fmtValue(mod) }); |
| 29119 | } | 29166 | } |
| 29120 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | 29167 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 29121 | .undef => try mod.undefRef(dest_ty), | 29168 | .undef => try mod.undefRef(dest_ty), |
| ... | @@ -29160,7 +29207,7 @@ fn coerceExtra( | ... | @@ -29160,7 +29207,7 @@ fn coerceExtra( |
| 29160 | block, | 29207 | block, |
| 29161 | inst_src, | 29208 | inst_src, |
| 29162 | "type '{}' cannot represent float value '{}'", | 29209 | "type '{}' cannot represent float value '{}'", |
| 29163 | .{ dest_ty.fmt(mod), val.fmtValue(inst_ty, mod) }, | 29210 | .{ dest_ty.fmt(mod), val.fmtValue(mod) }, |
| 29164 | ); | 29211 | ); |
| 29165 | } | 29212 | } |
| 29166 | return Air.internedToRef(result_val.toIntern()); | 29213 | return Air.internedToRef(result_val.toIntern()); |
| ... | @@ -29531,11 +29578,11 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -29531,11 +29578,11 @@ const InMemoryCoercionResult = union(enum) { |
| 29531 | .array_sentinel => |sentinel| { | 29578 | .array_sentinel => |sentinel| { |
| 29532 | if (sentinel.actual.toIntern() != .unreachable_value) { | 29579 | if (sentinel.actual.toIntern() != .unreachable_value) { |
| 29533 | try sema.errNote(block, src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{ | 29580 | try sema.errNote(block, src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{ |
| 29534 | sentinel.actual.fmtValue(sentinel.ty, mod), sentinel.wanted.fmtValue(sentinel.ty, mod), | 29581 | sentinel.actual.fmtValue(mod), sentinel.wanted.fmtValue(mod), |
| 29535 | }); | 29582 | }); |
| 29536 | } else { | 29583 | } else { |
| 29537 | try sema.errNote(block, src, msg, "destination array requires '{}' sentinel", .{ | 29584 | try sema.errNote(block, src, msg, "destination array requires '{}' sentinel", .{ |
| 29538 | sentinel.wanted.fmtValue(sentinel.ty, mod), | 29585 | sentinel.wanted.fmtValue(mod), |
| 29539 | }); | 29586 | }); |
| 29540 | } | 29587 | } |
| 29541 | break; | 29588 | break; |
| ... | @@ -29657,11 +29704,11 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -29657,11 +29704,11 @@ const InMemoryCoercionResult = union(enum) { |
| 29657 | .ptr_sentinel => |sentinel| { | 29704 | .ptr_sentinel => |sentinel| { |
| 29658 | if (sentinel.actual.toIntern() != .unreachable_value) { | 29705 | if (sentinel.actual.toIntern() != .unreachable_value) { |
| 29659 | try sema.errNote(block, src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{ | 29706 | try sema.errNote(block, src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{ |
| 29660 | sentinel.actual.fmtValue(sentinel.ty, mod), sentinel.wanted.fmtValue(sentinel.ty, mod), | 29707 | sentinel.actual.fmtValue(mod), sentinel.wanted.fmtValue(mod), |
| 29661 | }); | 29708 | }); |
| 29662 | } else { | 29709 | } else { |
| 29663 | try sema.errNote(block, src, msg, "destination pointer requires '{}' sentinel", .{ | 29710 | try sema.errNote(block, src, msg, "destination pointer requires '{}' sentinel", .{ |
| 29664 | sentinel.wanted.fmtValue(sentinel.ty, mod), | 29711 | sentinel.wanted.fmtValue(mod), |
| 29665 | }); | 29712 | }); |
| 29666 | } | 29713 | } |
| 29667 | break; | 29714 | break; |
| ... | @@ -30654,21 +30701,22 @@ fn storePtrVal( | ... | @@ -30654,21 +30701,22 @@ fn storePtrVal( |
| 30654 | .opv => {}, | 30701 | .opv => {}, |
| 30655 | .direct => |val_ptr| { | 30702 | .direct => |val_ptr| { |
| 30656 | if (mut_kit.root == .comptime_field) { | 30703 | if (mut_kit.root == .comptime_field) { |
| 30657 | val_ptr.* = Value.fromInterned((try val_ptr.intern(operand_ty, mod))); | 30704 | val_ptr.* = .{ .interned = try val_ptr.intern(mod, sema.arena) }; |
| 30658 | if (!operand_val.eql(val_ptr.*, operand_ty, mod)) { | 30705 | if (operand_val.toIntern() != val_ptr.interned) { |
| 30659 | // TODO use failWithInvalidComptimeFieldStore | 30706 | // TODO use failWithInvalidComptimeFieldStore |
| 30660 | return sema.fail(block, src, "value stored in comptime field does not match the default value of the field", .{}); | 30707 | return sema.fail(block, src, "value stored in comptime field does not match the default value of the field", .{}); |
| 30661 | } | 30708 | } |
| 30662 | return; | 30709 | return; |
| 30663 | } | 30710 | } |
| 30664 | val_ptr.* = Value.fromInterned((try operand_val.intern(operand_ty, mod))); | 30711 | val_ptr.* = .{ .interned = operand_val.toIntern() }; |
| 30665 | }, | 30712 | }, |
| 30666 | .reinterpret => |reinterpret| { | 30713 | .reinterpret => |reinterpret| { |
| 30667 | try sema.resolveTypeLayout(mut_kit.ty); | 30714 | try sema.resolveTypeLayout(mut_kit.ty); |
| 30668 | const abi_size = try sema.usizeCast(block, src, mut_kit.ty.abiSize(mod)); | 30715 | const abi_size = try sema.usizeCast(block, src, mut_kit.ty.abiSize(mod)); |
| 30669 | const buffer = try sema.gpa.alloc(u8, abi_size); | 30716 | const buffer = try sema.gpa.alloc(u8, abi_size); |
| 30670 | defer sema.gpa.free(buffer); | 30717 | defer sema.gpa.free(buffer); |
| 30671 | reinterpret.val_ptr.*.writeToMemory(mut_kit.ty, mod, buffer) catch |err| switch (err) { | 30718 | const interned_old = Value.fromInterned(try reinterpret.val_ptr.intern(mod, sema.arena)); |
| 30719 | interned_old.writeToMemory(mut_kit.ty, mod, buffer) catch |err| switch (err) { | ||
| 30672 | error.OutOfMemory => return error.OutOfMemory, | 30720 | error.OutOfMemory => return error.OutOfMemory, |
| 30673 | error.ReinterpretDeclRef => unreachable, | 30721 | error.ReinterpretDeclRef => unreachable, |
| 30674 | error.IllDefinedMemoryLayout => unreachable, // Sema was supposed to emit a compile error already | 30722 | error.IllDefinedMemoryLayout => unreachable, // Sema was supposed to emit a compile error already |
| ... | @@ -30692,7 +30740,7 @@ fn storePtrVal( | ... | @@ -30692,7 +30740,7 @@ fn storePtrVal( |
| 30692 | error.IllDefinedMemoryLayout => unreachable, | 30740 | error.IllDefinedMemoryLayout => unreachable, |
| 30693 | error.Unimplemented => return sema.fail(block, src, "TODO: implement readFromMemory for type '{}'", .{mut_kit.ty.fmt(mod)}), | 30741 | error.Unimplemented => return sema.fail(block, src, "TODO: implement readFromMemory for type '{}'", .{mut_kit.ty.fmt(mod)}), |
| 30694 | }; | 30742 | }; |
| 30695 | reinterpret.val_ptr.* = Value.fromInterned((try val.intern(mut_kit.ty, mod))); | 30743 | reinterpret.val_ptr.* = .{ .interned = val.toIntern() }; |
| 30696 | }, | 30744 | }, |
| 30697 | .bad_decl_ty, .bad_ptr_ty => { | 30745 | .bad_decl_ty, .bad_ptr_ty => { |
| 30698 | // TODO show the decl declaration site in a note and explain whether the decl | 30746 | // TODO show the decl declaration site in a note and explain whether the decl |
| ... | @@ -30717,11 +30765,11 @@ const ComptimePtrMutationKit = struct { | ... | @@ -30717,11 +30765,11 @@ const ComptimePtrMutationKit = struct { |
| 30717 | opv, | 30765 | opv, |
| 30718 | /// The pointer type matches the actual comptime Value so a direct | 30766 | /// The pointer type matches the actual comptime Value so a direct |
| 30719 | /// modification is possible. | 30767 | /// modification is possible. |
| 30720 | direct: *Value, | 30768 | direct: *MutableValue, |
| 30721 | /// The largest parent Value containing pointee and having a well-defined memory layout. | 30769 | /// The largest parent Value containing pointee and having a well-defined memory layout. |
| 30722 | /// This is used for bitcasting, if direct dereferencing failed. | 30770 | /// This is used for bitcasting, if direct dereferencing failed. |
| 30723 | reinterpret: struct { | 30771 | reinterpret: struct { |
| 30724 | val_ptr: *Value, | 30772 | val_ptr: *MutableValue, |
| 30725 | byte_offset: usize, | 30773 | byte_offset: usize, |
| 30726 | /// If set, write the operand to packed memory | 30774 | /// If set, write the operand to packed memory |
| 30727 | write_packed: bool = false, | 30775 | write_packed: bool = false, |
| ... | @@ -30753,15 +30801,15 @@ fn beginComptimePtrMutation( | ... | @@ -30753,15 +30801,15 @@ fn beginComptimePtrMutation( |
| 30753 | .decl, .anon_decl, .int => unreachable, // isComptimeMutablePtr has been checked already | 30801 | .decl, .anon_decl, .int => unreachable, // isComptimeMutablePtr has been checked already |
| 30754 | .comptime_alloc => |alloc_index| { | 30802 | .comptime_alloc => |alloc_index| { |
| 30755 | const alloc = sema.getComptimeAlloc(alloc_index); | 30803 | const alloc = sema.getComptimeAlloc(alloc_index); |
| 30756 | return sema.beginComptimePtrMutationInner(block, src, alloc.ty, &alloc.val, ptr_elem_ty, .{ .alloc = alloc_index }); | 30804 | return sema.beginComptimePtrMutationInner(block, src, alloc.val.typeOf(mod), &alloc.val, ptr_elem_ty, .{ .alloc = alloc_index }); |
| 30757 | }, | 30805 | }, |
| 30758 | .comptime_field => |comptime_field| { | 30806 | .comptime_field => |comptime_field| { |
| 30759 | const duped = try sema.arena.create(Value); | 30807 | const duped = try sema.arena.create(MutableValue); |
| 30760 | duped.* = Value.fromInterned(comptime_field); | 30808 | duped.* = .{ .interned = comptime_field }; |
| 30761 | return sema.beginComptimePtrMutationInner( | 30809 | return sema.beginComptimePtrMutationInner( |
| 30762 | block, | 30810 | block, |
| 30763 | src, | 30811 | src, |
| 30764 | Type.fromInterned(mod.intern_pool.typeOf(comptime_field)), | 30812 | duped.typeOf(mod), |
| 30765 | duped, | 30813 | duped, |
| 30766 | ptr_elem_ty, | 30814 | ptr_elem_ty, |
| 30767 | .comptime_field, | 30815 | .comptime_field, |
| ... | @@ -30774,36 +30822,28 @@ fn beginComptimePtrMutation( | ... | @@ -30774,36 +30822,28 @@ fn beginComptimePtrMutation( |
| 30774 | .opv => unreachable, | 30822 | .opv => unreachable, |
| 30775 | .direct => |val_ptr| { | 30823 | .direct => |val_ptr| { |
| 30776 | const payload_ty = parent.ty.errorUnionPayload(mod); | 30824 | const payload_ty = parent.ty.errorUnionPayload(mod); |
| 30777 | if (val_ptr.ip_index == .none and val_ptr.tag() == .eu_payload) { | 30825 | try val_ptr.unintern(mod, sema.arena, false, false); |
| 30778 | return ComptimePtrMutationKit{ | 30826 | if (val_ptr.* == .interned) { |
| 30779 | .root = parent.root, | ||
| 30780 | .pointee = .{ .direct = &val_ptr.castTag(.eu_payload).?.data }, | ||
| 30781 | .ty = payload_ty, | ||
| 30782 | }; | ||
| 30783 | } else { | ||
| 30784 | // An error union has been initialized to undefined at comptime and now we | 30827 | // An error union has been initialized to undefined at comptime and now we |
| 30785 | // are for the first time setting the payload. We must change the | 30828 | // are for the first time setting the payload. We must change the |
| 30786 | // representation of the error union from `undef` to `opt_payload`. | 30829 | // representation of the error union to `eu_payload`. |
| 30787 | 30830 | const child = try sema.arena.create(MutableValue); | |
| 30788 | const payload = try sema.arena.create(Value.Payload.SubValue); | 30831 | child.* = .{ .interned = try mod.intern(.{ .undef = payload_ty.toIntern() }) }; |
| 30789 | payload.* = .{ | 30832 | val_ptr.* = .{ .eu_payload = .{ |
| 30790 | .base = .{ .tag = .eu_payload }, | 30833 | .ty = parent.ty.toIntern(), |
| 30791 | .data = Value.fromInterned((try mod.intern(.{ .undef = payload_ty.toIntern() }))), | 30834 | .child = child, |
| 30792 | }; | 30835 | } }; |
| 30793 | |||
| 30794 | val_ptr.* = Value.initPayload(&payload.base); | ||
| 30795 | |||
| 30796 | return ComptimePtrMutationKit{ | ||
| 30797 | .root = parent.root, | ||
| 30798 | .pointee = .{ .direct = &payload.data }, | ||
| 30799 | .ty = payload_ty, | ||
| 30800 | }; | ||
| 30801 | } | 30836 | } |
| 30837 | return .{ | ||
| 30838 | .root = parent.root, | ||
| 30839 | .pointee = .{ .direct = val_ptr.eu_payload.child }, | ||
| 30840 | .ty = payload_ty, | ||
| 30841 | }; | ||
| 30802 | }, | 30842 | }, |
| 30803 | .bad_decl_ty, .bad_ptr_ty => return parent, | 30843 | .bad_decl_ty, .bad_ptr_ty => return parent, |
| 30804 | // Even though the parent value type has well-defined memory layout, our | 30844 | // Even though the parent value type has well-defined memory layout, our |
| 30805 | // pointer type does not. | 30845 | // pointer type does not. |
| 30806 | .reinterpret => return ComptimePtrMutationKit{ | 30846 | .reinterpret => return .{ |
| 30807 | .root = parent.root, | 30847 | .root = parent.root, |
| 30808 | .pointee = .bad_ptr_ty, | 30848 | .pointee = .bad_ptr_ty, |
| 30809 | .ty = eu_ty, | 30849 | .ty = eu_ty, |
| ... | @@ -30817,46 +30857,28 @@ fn beginComptimePtrMutation( | ... | @@ -30817,46 +30857,28 @@ fn beginComptimePtrMutation( |
| 30817 | .opv => unreachable, | 30857 | .opv => unreachable, |
| 30818 | .direct => |val_ptr| { | 30858 | .direct => |val_ptr| { |
| 30819 | const payload_ty = parent.ty.optionalChild(mod); | 30859 | const payload_ty = parent.ty.optionalChild(mod); |
| 30820 | switch (val_ptr.ip_index) { | 30860 | try val_ptr.unintern(mod, sema.arena, false, false); |
| 30821 | .none => return ComptimePtrMutationKit{ | 30861 | if (val_ptr.* == .interned) { |
| 30822 | .root = parent.root, | 30862 | // An optional has been initialized to undefined at comptime and now we |
| 30823 | .pointee = .{ .direct = &val_ptr.castTag(.opt_payload).?.data }, | 30863 | // are for the first time setting the payload. We must change the |
| 30824 | .ty = payload_ty, | 30864 | // representation of the optional to `opt_payload`. |
| 30825 | }, | 30865 | const child = try sema.arena.create(MutableValue); |
| 30826 | else => { | 30866 | child.* = .{ .interned = try mod.intern(.{ .undef = payload_ty.toIntern() }) }; |
| 30827 | const payload_val = switch (mod.intern_pool.indexToKey(val_ptr.ip_index)) { | 30867 | val_ptr.* = .{ .opt_payload = .{ |
| 30828 | .undef => try mod.intern(.{ .undef = payload_ty.toIntern() }), | 30868 | .ty = parent.ty.toIntern(), |
| 30829 | .opt => |opt| switch (opt.val) { | 30869 | .child = child, |
| 30830 | .none => try mod.intern(.{ .undef = payload_ty.toIntern() }), | 30870 | } }; |
| 30831 | else => |payload| payload, | ||
| 30832 | }, | ||
| 30833 | else => unreachable, | ||
| 30834 | }; | ||
| 30835 | |||
| 30836 | // An optional has been initialized to undefined at comptime and now we | ||
| 30837 | // are for the first time setting the payload. We must change the | ||
| 30838 | // representation of the optional from `undef` to `opt_payload`. | ||
| 30839 | |||
| 30840 | const payload = try sema.arena.create(Value.Payload.SubValue); | ||
| 30841 | payload.* = .{ | ||
| 30842 | .base = .{ .tag = .opt_payload }, | ||
| 30843 | .data = Value.fromInterned(payload_val), | ||
| 30844 | }; | ||
| 30845 | |||
| 30846 | val_ptr.* = Value.initPayload(&payload.base); | ||
| 30847 | |||
| 30848 | return ComptimePtrMutationKit{ | ||
| 30849 | .root = parent.root, | ||
| 30850 | .pointee = .{ .direct = &payload.data }, | ||
| 30851 | .ty = payload_ty, | ||
| 30852 | }; | ||
| 30853 | }, | ||
| 30854 | } | 30871 | } |
| 30872 | return .{ | ||
| 30873 | .root = parent.root, | ||
| 30874 | .pointee = .{ .direct = val_ptr.opt_payload.child }, | ||
| 30875 | .ty = payload_ty, | ||
| 30876 | }; | ||
| 30855 | }, | 30877 | }, |
| 30856 | .bad_decl_ty, .bad_ptr_ty => return parent, | 30878 | .bad_decl_ty, .bad_ptr_ty => return parent, |
| 30857 | // Even though the parent value type has well-defined memory layout, our | 30879 | // Even though the parent value type has well-defined memory layout, our |
| 30858 | // pointer type does not. | 30880 | // pointer type does not. |
| 30859 | .reinterpret => return ComptimePtrMutationKit{ | 30881 | .reinterpret => return .{ |
| 30860 | .root = parent.root, | 30882 | .root = parent.root, |
| 30861 | .pointee = .bad_ptr_ty, | 30883 | .pointee = .bad_ptr_ty, |
| 30862 | .ty = opt_ty, | 30884 | .ty = opt_ty, |
| ... | @@ -30915,106 +30937,28 @@ fn beginComptimePtrMutation( | ... | @@ -30915,106 +30937,28 @@ fn beginComptimePtrMutation( |
| 30915 | }; | 30937 | }; |
| 30916 | } | 30938 | } |
| 30917 | 30939 | ||
| 30918 | switch (val_ptr.ip_index) { | 30940 | try val_ptr.unintern(mod, sema.arena, false, false); |
| 30919 | .none => switch (val_ptr.tag()) { | 30941 | |
| 30920 | .bytes => { | 30942 | const aggregate = switch (val_ptr.*) { |
| 30921 | // An array is memory-optimized to store a slice of bytes, but we are about | 30943 | .interned, |
| 30922 | // to modify an individual field and the representation has to change. | 30944 | .bytes, |
| 30923 | // If we wanted to avoid this, there would need to be special detection | 30945 | .repeated, |
| 30924 | // elsewhere to identify when writing a value to an array element that is stored | 30946 | .eu_payload, |
| 30925 | // using the `bytes` tag, and handle it without making a call to this function. | 30947 | .opt_payload, |
| 30926 | const arena = sema.arena; | 30948 | .slice, |
| 30927 | 30949 | .un, | |
| 30928 | const bytes = val_ptr.castTag(.bytes).?.data; | 30950 | => unreachable, |
| 30929 | const dest_len = parent.ty.arrayLenIncludingSentinel(mod); | 30951 | .aggregate => |*a| a, |
| 30930 | // bytes.len may be one greater than dest_len because of the case when | 30952 | }; |
| 30931 | // assigning `[N:S]T` to `[N]T`. This is allowed; the sentinel is omitted. | ||
| 30932 | assert(bytes.len >= dest_len); | ||
| 30933 | const elems = try arena.alloc(Value, @intCast(dest_len)); | ||
| 30934 | for (elems, 0..) |*elem, i| { | ||
| 30935 | elem.* = try mod.intValue(elem_ty, bytes[i]); | ||
| 30936 | } | ||
| 30937 | |||
| 30938 | val_ptr.* = try Value.Tag.aggregate.create(arena, elems); | ||
| 30939 | |||
| 30940 | return beginComptimePtrMutationInner( | ||
| 30941 | sema, | ||
| 30942 | block, | ||
| 30943 | src, | ||
| 30944 | elem_ty, | ||
| 30945 | &elems[@intCast(elem_ptr.index)], | ||
| 30946 | ptr_elem_ty, | ||
| 30947 | parent.root, | ||
| 30948 | ); | ||
| 30949 | }, | ||
| 30950 | .repeated => { | ||
| 30951 | // An array is memory-optimized to store only a single element value, and | ||
| 30952 | // that value is understood to be the same for the entire length of the array. | ||
| 30953 | // However, now we want to modify an individual field and so the | ||
| 30954 | // representation has to change. If we wanted to avoid this, there would | ||
| 30955 | // need to be special detection elsewhere to identify when writing a value to an | ||
| 30956 | // array element that is stored using the `repeated` tag, and handle it | ||
| 30957 | // without making a call to this function. | ||
| 30958 | const arena = sema.arena; | ||
| 30959 | |||
| 30960 | const repeated_val = try val_ptr.castTag(.repeated).?.data.intern(parent.ty.childType(mod), mod); | ||
| 30961 | const array_len_including_sentinel = | ||
| 30962 | try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel(mod)); | ||
| 30963 | const elems = try arena.alloc(Value, array_len_including_sentinel); | ||
| 30964 | @memset(elems, Value.fromInterned(repeated_val)); | ||
| 30965 | |||
| 30966 | val_ptr.* = try Value.Tag.aggregate.create(arena, elems); | ||
| 30967 | |||
| 30968 | return beginComptimePtrMutationInner( | ||
| 30969 | sema, | ||
| 30970 | block, | ||
| 30971 | src, | ||
| 30972 | elem_ty, | ||
| 30973 | &elems[@intCast(elem_ptr.index)], | ||
| 30974 | ptr_elem_ty, | ||
| 30975 | parent.root, | ||
| 30976 | ); | ||
| 30977 | }, | ||
| 30978 | |||
| 30979 | .aggregate => return beginComptimePtrMutationInner( | ||
| 30980 | sema, | ||
| 30981 | block, | ||
| 30982 | src, | ||
| 30983 | elem_ty, | ||
| 30984 | &val_ptr.castTag(.aggregate).?.data[@intCast(elem_ptr.index)], | ||
| 30985 | ptr_elem_ty, | ||
| 30986 | parent.root, | ||
| 30987 | ), | ||
| 30988 | 30953 | ||
| 30989 | else => unreachable, | 30954 | return sema.beginComptimePtrMutationInner( |
| 30990 | }, | 30955 | block, |
| 30991 | else => switch (mod.intern_pool.indexToKey(val_ptr.toIntern())) { | 30956 | src, |
| 30992 | .undef => { | 30957 | elem_ty, |
| 30993 | // An array has been initialized to undefined at comptime and now we | 30958 | &aggregate.elems[@intCast(elem_ptr.index)], |
| 30994 | // are for the first time setting an element. We must change the representation | 30959 | ptr_elem_ty, |
| 30995 | // of the array from `undef` to `array`. | 30960 | parent.root, |
| 30996 | const arena = sema.arena; | 30961 | ); |
| 30997 | |||
| 30998 | const array_len_including_sentinel = | ||
| 30999 | try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel(mod)); | ||
| 31000 | const elems = try arena.alloc(Value, array_len_including_sentinel); | ||
| 31001 | @memset(elems, Value.fromInterned((try mod.intern(.{ .undef = elem_ty.toIntern() })))); | ||
| 31002 | |||
| 31003 | val_ptr.* = try Value.Tag.aggregate.create(arena, elems); | ||
| 31004 | |||
| 31005 | return beginComptimePtrMutationInner( | ||
| 31006 | sema, | ||
| 31007 | block, | ||
| 31008 | src, | ||
| 31009 | elem_ty, | ||
| 31010 | &elems[@intCast(elem_ptr.index)], | ||
| 31011 | ptr_elem_ty, | ||
| 31012 | parent.root, | ||
| 31013 | ); | ||
| 31014 | }, | ||
| 31015 | else => unreachable, | ||
| 31016 | }, | ||
| 31017 | } | ||
| 31018 | }, | 30962 | }, |
| 31019 | else => { | 30963 | else => { |
| 31020 | if (elem_ptr.index != 0) { | 30964 | if (elem_ptr.index != 0) { |
| ... | @@ -31038,7 +30982,7 @@ fn beginComptimePtrMutation( | ... | @@ -31038,7 +30982,7 @@ fn beginComptimePtrMutation( |
| 31038 | if (!base_elem_ty.hasWellDefinedLayout(mod)) { | 30982 | if (!base_elem_ty.hasWellDefinedLayout(mod)) { |
| 31039 | // Even though the parent value type has well-defined memory layout, our | 30983 | // Even though the parent value type has well-defined memory layout, our |
| 31040 | // pointer type does not. | 30984 | // pointer type does not. |
| 31041 | return ComptimePtrMutationKit{ | 30985 | return .{ |
| 31042 | .root = parent.root, | 30986 | .root = parent.root, |
| 31043 | .pointee = .bad_ptr_ty, | 30987 | .pointee = .bad_ptr_ty, |
| 31044 | .ty = base_elem_ty, | 30988 | .ty = base_elem_ty, |
| ... | @@ -31048,7 +30992,7 @@ fn beginComptimePtrMutation( | ... | @@ -31048,7 +30992,7 @@ fn beginComptimePtrMutation( |
| 31048 | const elem_abi_size_u64 = try sema.typeAbiSize(base_elem_ty); | 30992 | const elem_abi_size_u64 = try sema.typeAbiSize(base_elem_ty); |
| 31049 | const elem_abi_size = try sema.usizeCast(block, src, elem_abi_size_u64); | 30993 | const elem_abi_size = try sema.usizeCast(block, src, elem_abi_size_u64); |
| 31050 | const elem_idx = try sema.usizeCast(block, src, elem_ptr.index); | 30994 | const elem_idx = try sema.usizeCast(block, src, elem_ptr.index); |
| 31051 | return ComptimePtrMutationKit{ | 30995 | return .{ |
| 31052 | .root = parent.root, | 30996 | .root = parent.root, |
| 31053 | .pointee = .{ .reinterpret = .{ | 30997 | .pointee = .{ .reinterpret = .{ |
| 31054 | .val_ptr = reinterpret.val_ptr, | 30998 | .val_ptr = reinterpret.val_ptr, |
| ... | @@ -31067,56 +31011,68 @@ fn beginComptimePtrMutation( | ... | @@ -31067,56 +31011,68 @@ fn beginComptimePtrMutation( |
| 31067 | var parent = try sema.beginComptimePtrMutation(block, src, Value.fromInterned(field_ptr.base), base_child_ty); | 31011 | var parent = try sema.beginComptimePtrMutation(block, src, Value.fromInterned(field_ptr.base), base_child_ty); |
| 31068 | switch (parent.pointee) { | 31012 | switch (parent.pointee) { |
| 31069 | .opv => unreachable, | 31013 | .opv => unreachable, |
| 31070 | .direct => |val_ptr| switch (val_ptr.ip_index) { | 31014 | .direct => |val_ptr| { |
| 31071 | .empty_struct => { | 31015 | try val_ptr.unintern(mod, sema.arena, false, false); |
| 31072 | const duped = try sema.arena.create(Value); | 31016 | switch (val_ptr.*) { |
| 31073 | duped.* = val_ptr.*; | 31017 | .interned, |
| 31074 | return beginComptimePtrMutationInner( | 31018 | .eu_payload, |
| 31075 | sema, | 31019 | .opt_payload, |
| 31076 | block, | 31020 | .repeated, |
| 31077 | src, | 31021 | .bytes, |
| 31078 | parent.ty.structFieldType(field_index, mod), | 31022 | => unreachable, |
| 31079 | duped, | 31023 | .aggregate => |*a| return sema.beginComptimePtrMutationInner( |
| 31080 | ptr_elem_ty, | ||
| 31081 | parent.root, | ||
| 31082 | ); | ||
| 31083 | }, | ||
| 31084 | .none => switch (val_ptr.tag()) { | ||
| 31085 | .aggregate => return beginComptimePtrMutationInner( | ||
| 31086 | sema, | ||
| 31087 | block, | 31024 | block, |
| 31088 | src, | 31025 | src, |
| 31089 | parent.ty.structFieldType(field_index, mod), | 31026 | parent.ty.structFieldType(field_index, mod), |
| 31090 | &val_ptr.castTag(.aggregate).?.data[field_index], | 31027 | &a.elems[field_index], |
| 31091 | ptr_elem_ty, | 31028 | ptr_elem_ty, |
| 31092 | parent.root, | 31029 | parent.root, |
| 31093 | ), | 31030 | ), |
| 31094 | .repeated => { | 31031 | .slice => |*s| switch (field_index) { |
| 31095 | const arena = sema.arena; | 31032 | Value.slice_ptr_index => return sema.beginComptimePtrMutationInner( |
| 31096 | |||
| 31097 | const elems = try arena.alloc(Value, parent.ty.structFieldCount(mod)); | ||
| 31098 | @memset(elems, val_ptr.castTag(.repeated).?.data); | ||
| 31099 | val_ptr.* = try Value.Tag.aggregate.create(arena, elems); | ||
| 31100 | |||
| 31101 | return beginComptimePtrMutationInner( | ||
| 31102 | sema, | ||
| 31103 | block, | 31033 | block, |
| 31104 | src, | 31034 | src, |
| 31105 | parent.ty.structFieldType(field_index, mod), | 31035 | parent.ty.slicePtrFieldType(mod), |
| 31106 | &elems[field_index], | 31036 | s.ptr, |
| 31107 | ptr_elem_ty, | 31037 | ptr_elem_ty, |
| 31108 | parent.root, | 31038 | parent.root, |
| 31109 | ); | 31039 | ), |
| 31040 | Value.slice_len_index => return sema.beginComptimePtrMutationInner( | ||
| 31041 | block, | ||
| 31042 | src, | ||
| 31043 | Type.usize, | ||
| 31044 | s.len, | ||
| 31045 | ptr_elem_ty, | ||
| 31046 | parent.root, | ||
| 31047 | ), | ||
| 31048 | else => unreachable, | ||
| 31110 | }, | 31049 | }, |
| 31111 | .@"union" => { | 31050 | .un => |*un| { |
| 31112 | const payload = &val_ptr.castTag(.@"union").?.data; | ||
| 31113 | const layout = base_child_ty.containerLayout(mod); | 31051 | const layout = base_child_ty.containerLayout(mod); |
| 31114 | 31052 | ||
| 31115 | const tag_type = base_child_ty.unionTagTypeHypothetical(mod); | 31053 | const tag_type = base_child_ty.unionTagTypeHypothetical(mod); |
| 31116 | const hypothetical_tag = try mod.enumValueFieldIndex(tag_type, field_index); | 31054 | const hypothetical_tag = try mod.enumValueFieldIndex(tag_type, field_index); |
| 31117 | if (layout == .auto or (payload.tag != null and hypothetical_tag.eql(payload.tag.?, tag_type, mod))) { | 31055 | if (un.tag == .none and un.payload.* == .interned and un.payload.interned == .undef) { |
| 31056 | // A union has been initialized to undefined at comptime and now we | ||
| 31057 | // are for the first time setting the payload. We must change the | ||
| 31058 | // tag implicitly. | ||
| 31059 | const payload_ty = parent.ty.structFieldType(field_index, mod); | ||
| 31060 | un.tag = hypothetical_tag.toIntern(); | ||
| 31061 | un.payload.* = .{ .interned = try mod.intern(.{ .undef = payload_ty.toIntern() }) }; | ||
| 31062 | return beginComptimePtrMutationInner( | ||
| 31063 | sema, | ||
| 31064 | block, | ||
| 31065 | src, | ||
| 31066 | payload_ty, | ||
| 31067 | un.payload, | ||
| 31068 | ptr_elem_ty, | ||
| 31069 | parent.root, | ||
| 31070 | ); | ||
| 31071 | } | ||
| 31072 | |||
| 31073 | if (layout == .auto or hypothetical_tag.toIntern() == un.tag) { | ||
| 31118 | // We need to set the active field of the union. | 31074 | // We need to set the active field of the union. |
| 31119 | payload.tag = hypothetical_tag; | 31075 | un.tag = hypothetical_tag.toIntern(); |
| 31120 | 31076 | ||
| 31121 | const field_ty = parent.ty.structFieldType(field_index, mod); | 31077 | const field_ty = parent.ty.structFieldType(field_index, mod); |
| 31122 | return beginComptimePtrMutationInner( | 31078 | return beginComptimePtrMutationInner( |
| ... | @@ -31124,7 +31080,7 @@ fn beginComptimePtrMutation( | ... | @@ -31124,7 +31080,7 @@ fn beginComptimePtrMutation( |
| 31124 | block, | 31080 | block, |
| 31125 | src, | 31081 | src, |
| 31126 | field_ty, | 31082 | field_ty, |
| 31127 | &payload.val, | 31083 | un.payload, |
| 31128 | ptr_elem_ty, | 31084 | ptr_elem_ty, |
| 31129 | parent.root, | 31085 | parent.root, |
| 31130 | ); | 31086 | ); |
| ... | @@ -31132,11 +31088,10 @@ fn beginComptimePtrMutation( | ... | @@ -31132,11 +31088,10 @@ fn beginComptimePtrMutation( |
| 31132 | // Writing to a different field (a different or unknown tag is active) requires reinterpreting | 31088 | // Writing to a different field (a different or unknown tag is active) requires reinterpreting |
| 31133 | // memory of the entire union, which requires knowing its abiSize. | 31089 | // memory of the entire union, which requires knowing its abiSize. |
| 31134 | try sema.resolveTypeLayout(parent.ty); | 31090 | try sema.resolveTypeLayout(parent.ty); |
| 31135 | |||
| 31136 | // This union value no longer has a well-defined tag type. | 31091 | // This union value no longer has a well-defined tag type. |
| 31137 | // The reinterpretation will read it back out as .none. | 31092 | // The reinterpretation will read it back out as .none. |
| 31138 | payload.val = try payload.val.unintern(sema.arena, mod); | 31093 | try un.payload.unintern(mod, sema.arena, false, false); |
| 31139 | return ComptimePtrMutationKit{ | 31094 | return .{ |
| 31140 | .root = parent.root, | 31095 | .root = parent.root, |
| 31141 | .pointee = .{ .reinterpret = .{ | 31096 | .pointee = .{ .reinterpret = .{ |
| 31142 | .val_ptr = val_ptr, | 31097 | .val_ptr = val_ptr, |
| ... | @@ -31147,119 +31102,12 @@ fn beginComptimePtrMutation( | ... | @@ -31147,119 +31102,12 @@ fn beginComptimePtrMutation( |
| 31147 | }; | 31102 | }; |
| 31148 | } | 31103 | } |
| 31149 | }, | 31104 | }, |
| 31150 | .slice => switch (field_index) { | 31105 | } |
| 31151 | Value.slice_ptr_index => return beginComptimePtrMutationInner( | ||
| 31152 | sema, | ||
| 31153 | block, | ||
| 31154 | src, | ||
| 31155 | parent.ty.slicePtrFieldType(mod), | ||
| 31156 | &val_ptr.castTag(.slice).?.data.ptr, | ||
| 31157 | ptr_elem_ty, | ||
| 31158 | parent.root, | ||
| 31159 | ), | ||
| 31160 | |||
| 31161 | Value.slice_len_index => return beginComptimePtrMutationInner( | ||
| 31162 | sema, | ||
| 31163 | block, | ||
| 31164 | src, | ||
| 31165 | Type.usize, | ||
| 31166 | &val_ptr.castTag(.slice).?.data.len, | ||
| 31167 | ptr_elem_ty, | ||
| 31168 | parent.root, | ||
| 31169 | ), | ||
| 31170 | |||
| 31171 | else => unreachable, | ||
| 31172 | }, | ||
| 31173 | else => unreachable, | ||
| 31174 | }, | ||
| 31175 | else => switch (mod.intern_pool.indexToKey(val_ptr.toIntern())) { | ||
| 31176 | .undef => { | ||
| 31177 | // A struct or union has been initialized to undefined at comptime and now we | ||
| 31178 | // are for the first time setting a field. We must change the representation | ||
| 31179 | // of the struct/union from `undef` to `struct`/`union`. | ||
| 31180 | const arena = sema.arena; | ||
| 31181 | |||
| 31182 | switch (parent.ty.zigTypeTag(mod)) { | ||
| 31183 | .Struct => { | ||
| 31184 | const fields = try arena.alloc(Value, parent.ty.structFieldCount(mod)); | ||
| 31185 | for (fields, 0..) |*field, i| field.* = Value.fromInterned((try mod.intern(.{ | ||
| 31186 | .undef = parent.ty.structFieldType(i, mod).toIntern(), | ||
| 31187 | }))); | ||
| 31188 | |||
| 31189 | val_ptr.* = try Value.Tag.aggregate.create(arena, fields); | ||
| 31190 | |||
| 31191 | return beginComptimePtrMutationInner( | ||
| 31192 | sema, | ||
| 31193 | block, | ||
| 31194 | src, | ||
| 31195 | parent.ty.structFieldType(field_index, mod), | ||
| 31196 | &fields[field_index], | ||
| 31197 | ptr_elem_ty, | ||
| 31198 | parent.root, | ||
| 31199 | ); | ||
| 31200 | }, | ||
| 31201 | .Union => { | ||
| 31202 | const payload = try arena.create(Value.Payload.Union); | ||
| 31203 | const tag_ty = parent.ty.unionTagTypeHypothetical(mod); | ||
| 31204 | const payload_ty = parent.ty.structFieldType(field_index, mod); | ||
| 31205 | payload.* = .{ .data = .{ | ||
| 31206 | .tag = try mod.enumValueFieldIndex(tag_ty, field_index), | ||
| 31207 | .val = Value.fromInterned((try mod.intern(.{ .undef = payload_ty.toIntern() }))), | ||
| 31208 | } }; | ||
| 31209 | |||
| 31210 | val_ptr.* = Value.initPayload(&payload.base); | ||
| 31211 | |||
| 31212 | return beginComptimePtrMutationInner( | ||
| 31213 | sema, | ||
| 31214 | block, | ||
| 31215 | src, | ||
| 31216 | payload_ty, | ||
| 31217 | &payload.data.val, | ||
| 31218 | ptr_elem_ty, | ||
| 31219 | parent.root, | ||
| 31220 | ); | ||
| 31221 | }, | ||
| 31222 | .Pointer => { | ||
| 31223 | assert(parent.ty.isSlice(mod)); | ||
| 31224 | const ptr_ty = parent.ty.slicePtrFieldType(mod); | ||
| 31225 | val_ptr.* = try Value.Tag.slice.create(arena, .{ | ||
| 31226 | .ptr = Value.fromInterned((try mod.intern(.{ .undef = ptr_ty.toIntern() }))), | ||
| 31227 | .len = Value.fromInterned((try mod.intern(.{ .undef = .usize_type }))), | ||
| 31228 | }); | ||
| 31229 | |||
| 31230 | switch (field_index) { | ||
| 31231 | Value.slice_ptr_index => return beginComptimePtrMutationInner( | ||
| 31232 | sema, | ||
| 31233 | block, | ||
| 31234 | src, | ||
| 31235 | ptr_ty, | ||
| 31236 | &val_ptr.castTag(.slice).?.data.ptr, | ||
| 31237 | ptr_elem_ty, | ||
| 31238 | parent.root, | ||
| 31239 | ), | ||
| 31240 | Value.slice_len_index => return beginComptimePtrMutationInner( | ||
| 31241 | sema, | ||
| 31242 | block, | ||
| 31243 | src, | ||
| 31244 | Type.usize, | ||
| 31245 | &val_ptr.castTag(.slice).?.data.len, | ||
| 31246 | ptr_elem_ty, | ||
| 31247 | parent.root, | ||
| 31248 | ), | ||
| 31249 | |||
| 31250 | else => unreachable, | ||
| 31251 | } | ||
| 31252 | }, | ||
| 31253 | else => unreachable, | ||
| 31254 | } | ||
| 31255 | }, | ||
| 31256 | else => unreachable, | ||
| 31257 | }, | ||
| 31258 | }, | 31106 | }, |
| 31259 | .reinterpret => |reinterpret| { | 31107 | .reinterpret => |reinterpret| { |
| 31260 | const field_offset_u64 = base_child_ty.structFieldOffset(field_index, mod); | 31108 | const field_offset_u64 = base_child_ty.structFieldOffset(field_index, mod); |
| 31261 | const field_offset = try sema.usizeCast(block, src, field_offset_u64); | 31109 | const field_offset = try sema.usizeCast(block, src, field_offset_u64); |
| 31262 | return ComptimePtrMutationKit{ | 31110 | return .{ |
| 31263 | .root = parent.root, | 31111 | .root = parent.root, |
| 31264 | .pointee = .{ .reinterpret = .{ | 31112 | .pointee = .{ .reinterpret = .{ |
| 31265 | .val_ptr = reinterpret.val_ptr, | 31113 | .val_ptr = reinterpret.val_ptr, |
| ... | @@ -31279,7 +31127,7 @@ fn beginComptimePtrMutationInner( | ... | @@ -31279,7 +31127,7 @@ fn beginComptimePtrMutationInner( |
| 31279 | block: *Block, | 31127 | block: *Block, |
| 31280 | src: LazySrcLoc, | 31128 | src: LazySrcLoc, |
| 31281 | decl_ty: Type, | 31129 | decl_ty: Type, |
| 31282 | decl_val: *Value, | 31130 | decl_val: *MutableValue, |
| 31283 | ptr_elem_ty: Type, | 31131 | ptr_elem_ty: Type, |
| 31284 | root: ComptimePtrMutationKit.Root, | 31132 | root: ComptimePtrMutationKit.Root, |
| 31285 | ) CompileError!ComptimePtrMutationKit { | 31133 | ) CompileError!ComptimePtrMutationKit { |
| ... | @@ -31287,7 +31135,13 @@ fn beginComptimePtrMutationInner( | ... | @@ -31287,7 +31135,13 @@ fn beginComptimePtrMutationInner( |
| 31287 | const target = mod.getTarget(); | 31135 | const target = mod.getTarget(); |
| 31288 | const coerce_ok = (try sema.coerceInMemoryAllowed(block, ptr_elem_ty, decl_ty, true, target, src, src)) == .ok; | 31136 | const coerce_ok = (try sema.coerceInMemoryAllowed(block, ptr_elem_ty, decl_ty, true, target, src, src)) == .ok; |
| 31289 | 31137 | ||
| 31290 | decl_val.* = try decl_val.unintern(sema.arena, mod); | 31138 | const old_decl_val = decl_val.*; |
| 31139 | try decl_val.unintern(mod, sema.arena, false, false); | ||
| 31140 | if (decl_val.* == .un and decl_val.un.tag == .none and decl_val.un.payload.* == .interned and decl_val.un.payload.interned == .undef) { | ||
| 31141 | // HACKHACK: undefined union - re-intern it for now | ||
| 31142 | // `unintern` probably should just leave these as is, but I'm leaving it until I rewrite comptime pointer access. | ||
| 31143 | decl_val.* = old_decl_val; | ||
| 31144 | } | ||
| 31291 | 31145 | ||
| 31292 | if (coerce_ok) { | 31146 | if (coerce_ok) { |
| 31293 | return ComptimePtrMutationKit{ | 31147 | return ComptimePtrMutationKit{ |
| ... | @@ -31333,21 +31187,16 @@ fn beginComptimePtrMutationInner( | ... | @@ -31333,21 +31187,16 @@ fn beginComptimePtrMutationInner( |
| 31333 | }; | 31187 | }; |
| 31334 | } | 31188 | } |
| 31335 | 31189 | ||
| 31336 | const TypedValueAndOffset = struct { | ||
| 31337 | tv: TypedValue, | ||
| 31338 | byte_offset: usize, | ||
| 31339 | }; | ||
| 31340 | |||
| 31341 | const ComptimePtrLoadKit = struct { | 31190 | const ComptimePtrLoadKit = struct { |
| 31342 | /// The Value and Type corresponding to the pointee of the provided pointer. | 31191 | /// The Value and Type corresponding to the pointee of the provided pointer. |
| 31343 | /// If a direct dereference is not possible, this is null. | 31192 | /// If a direct dereference is not possible, this is null. |
| 31344 | pointee: ?TypedValue, | 31193 | pointee: ?MutableValue, |
| 31345 | /// The largest parent Value containing `pointee` and having a well-defined memory layout. | 31194 | /// The largest parent Value containing `pointee` and having a well-defined memory layout. |
| 31346 | /// This is used for bitcasting, if direct dereferencing failed (i.e. `pointee` is null). | 31195 | /// This is used for bitcasting, if direct dereferencing failed (i.e. `pointee` is null). |
| 31347 | parent: ?TypedValueAndOffset, | 31196 | parent: ?struct { |
| 31348 | /// Whether the `pointee` could be mutated by further | 31197 | val: MutableValue, |
| 31349 | /// semantic analysis and a copy must be performed. | 31198 | byte_offset: usize, |
| 31350 | is_mutable: bool, | 31199 | }, |
| 31351 | /// If the root decl could not be used as `parent`, this is the type that | 31200 | /// If the root decl could not be used as `parent`, this is the type that |
| 31352 | /// caused that by not having a well-defined layout | 31201 | /// caused that by not having a well-defined layout |
| 31353 | ty_without_well_defined_layout: ?Type, | 31202 | ty_without_well_defined_layout: ?Type, |
| ... | @@ -31374,53 +31223,41 @@ fn beginComptimePtrLoad( | ... | @@ -31374,53 +31223,41 @@ fn beginComptimePtrLoad( |
| 31374 | .ptr => |ptr| switch (ptr.addr) { | 31223 | .ptr => |ptr| switch (ptr.addr) { |
| 31375 | .decl => |decl_index| blk: { | 31224 | .decl => |decl_index| blk: { |
| 31376 | const decl = mod.declPtr(decl_index); | 31225 | const decl = mod.declPtr(decl_index); |
| 31377 | const decl_tv = try decl.typedValue(); | ||
| 31378 | try sema.declareDependency(.{ .decl_val = decl_index }); | 31226 | try sema.declareDependency(.{ .decl_val = decl_index }); |
| 31379 | if (decl.val.getVariable(mod) != null) return error.RuntimeLoad; | 31227 | if (decl.val.getVariable(mod) != null) return error.RuntimeLoad; |
| 31380 | 31228 | const decl_val: MutableValue = .{ .interned = decl.val.toIntern() }; | |
| 31381 | const layout_defined = decl.ty.hasWellDefinedLayout(mod); | 31229 | const layout_defined = decl.typeOf(mod).hasWellDefinedLayout(mod); |
| 31382 | break :blk ComptimePtrLoadKit{ | 31230 | break :blk ComptimePtrLoadKit{ |
| 31383 | .parent = if (layout_defined) .{ .tv = decl_tv, .byte_offset = 0 } else null, | 31231 | .parent = if (layout_defined) .{ .val = decl_val, .byte_offset = 0 } else null, |
| 31384 | .pointee = decl_tv, | 31232 | .pointee = decl_val, |
| 31385 | .is_mutable = false, | 31233 | .ty_without_well_defined_layout = if (!layout_defined) decl.typeOf(mod) else null, |
| 31386 | .ty_without_well_defined_layout = if (!layout_defined) decl.ty else null, | ||
| 31387 | }; | 31234 | }; |
| 31388 | }, | 31235 | }, |
| 31389 | .comptime_alloc => |alloc_index| kit: { | 31236 | .comptime_alloc => |alloc_index| kit: { |
| 31390 | const alloc = sema.getComptimeAlloc(alloc_index); | 31237 | const alloc = sema.getComptimeAlloc(alloc_index); |
| 31391 | const alloc_tv: TypedValue = .{ | 31238 | const alloc_ty = alloc.val.typeOf(mod); |
| 31392 | .ty = alloc.ty, | 31239 | const layout_defined = alloc_ty.hasWellDefinedLayout(mod); |
| 31393 | .val = alloc.val, | ||
| 31394 | }; | ||
| 31395 | const layout_defined = alloc.ty.hasWellDefinedLayout(mod); | ||
| 31396 | break :kit .{ | 31240 | break :kit .{ |
| 31397 | .parent = if (layout_defined) .{ .tv = alloc_tv, .byte_offset = 0 } else null, | 31241 | .parent = if (layout_defined) .{ .val = alloc.val, .byte_offset = 0 } else null, |
| 31398 | .pointee = alloc_tv, | 31242 | .pointee = alloc.val, |
| 31399 | .is_mutable = true, | 31243 | .ty_without_well_defined_layout = if (!layout_defined) alloc_ty else null, |
| 31400 | .ty_without_well_defined_layout = if (!layout_defined) alloc.ty else null, | ||
| 31401 | }; | 31244 | }; |
| 31402 | }, | 31245 | }, |
| 31403 | .anon_decl => |anon_decl| blk: { | 31246 | .anon_decl => |anon_decl| blk: { |
| 31404 | const decl_val = anon_decl.val; | 31247 | const decl_val = anon_decl.val; |
| 31405 | if (Value.fromInterned(decl_val).getVariable(mod) != null) return error.RuntimeLoad; | 31248 | if (Value.fromInterned(decl_val).getVariable(mod) != null) return error.RuntimeLoad; |
| 31406 | const decl_ty = Type.fromInterned(ip.typeOf(decl_val)); | 31249 | const decl_ty = Type.fromInterned(ip.typeOf(decl_val)); |
| 31407 | const decl_tv: TypedValue = .{ .ty = decl_ty, .val = Value.fromInterned(decl_val) }; | 31250 | const decl_mv: MutableValue = .{ .interned = decl_val }; |
| 31408 | const layout_defined = decl_ty.hasWellDefinedLayout(mod); | 31251 | const layout_defined = decl_ty.hasWellDefinedLayout(mod); |
| 31409 | break :blk ComptimePtrLoadKit{ | 31252 | break :blk ComptimePtrLoadKit{ |
| 31410 | .parent = if (layout_defined) .{ .tv = decl_tv, .byte_offset = 0 } else null, | 31253 | .parent = if (layout_defined) .{ .val = decl_mv, .byte_offset = 0 } else null, |
| 31411 | .pointee = decl_tv, | 31254 | .pointee = decl_mv, |
| 31412 | .is_mutable = false, | ||
| 31413 | .ty_without_well_defined_layout = if (!layout_defined) decl_ty else null, | 31255 | .ty_without_well_defined_layout = if (!layout_defined) decl_ty else null, |
| 31414 | }; | 31256 | }; |
| 31415 | }, | 31257 | }, |
| 31416 | .int => return error.RuntimeLoad, | 31258 | .int => return error.RuntimeLoad, |
| 31417 | .eu_payload, .opt_payload => |container_ptr| blk: { | 31259 | .eu_payload, .opt_payload => |container_ptr| blk: { |
| 31418 | const container_ty = Type.fromInterned(ip.typeOf(container_ptr)).childType(mod); | 31260 | const container_ty = Type.fromInterned(ip.typeOf(container_ptr)).childType(mod); |
| 31419 | const payload_ty = switch (ptr.addr) { | ||
| 31420 | .eu_payload => container_ty.errorUnionPayload(mod), | ||
| 31421 | .opt_payload => container_ty.optionalChild(mod), | ||
| 31422 | else => unreachable, | ||
| 31423 | }; | ||
| 31424 | var deref = try sema.beginComptimePtrLoad(block, src, Value.fromInterned(container_ptr), container_ty); | 31261 | var deref = try sema.beginComptimePtrLoad(block, src, Value.fromInterned(container_ptr), container_ty); |
| 31425 | 31262 | ||
| 31426 | // eu_payload and opt_payload never have a well-defined layout | 31263 | // eu_payload and opt_payload never have a well-defined layout |
| ... | @@ -31429,15 +31266,14 @@ fn beginComptimePtrLoad( | ... | @@ -31429,15 +31266,14 @@ fn beginComptimePtrLoad( |
| 31429 | deref.ty_without_well_defined_layout = container_ty; | 31266 | deref.ty_without_well_defined_layout = container_ty; |
| 31430 | } | 31267 | } |
| 31431 | 31268 | ||
| 31432 | if (deref.pointee) |*tv| { | 31269 | if (deref.pointee) |pointee| { |
| 31270 | const pointee_ty = pointee.typeOf(mod); | ||
| 31433 | const coerce_in_mem_ok = | 31271 | const coerce_in_mem_ok = |
| 31434 | (try sema.coerceInMemoryAllowed(block, container_ty, tv.ty, false, target, src, src)) == .ok or | 31272 | (try sema.coerceInMemoryAllowed(block, container_ty, pointee_ty, false, target, src, src)) == .ok or |
| 31435 | (try sema.coerceInMemoryAllowed(block, tv.ty, container_ty, false, target, src, src)) == .ok; | 31273 | (try sema.coerceInMemoryAllowed(block, pointee_ty, container_ty, false, target, src, src)) == .ok; |
| 31436 | if (coerce_in_mem_ok) { | 31274 | if (coerce_in_mem_ok) { |
| 31437 | const payload_val = switch (tv.val.ip_index) { | 31275 | deref.pointee = switch (pointee) { |
| 31438 | .none => tv.val.cast(Value.Payload.SubValue).?.data, | 31276 | .interned => |ip_index| .{ .interned = switch (ip.indexToKey(ip_index)) { |
| 31439 | .null_value => return sema.fail(block, src, "attempt to use null value", .{}), | ||
| 31440 | else => Value.fromInterned(switch (ip.indexToKey(tv.val.toIntern())) { | ||
| 31441 | .error_union => |error_union| switch (error_union.val) { | 31277 | .error_union => |error_union| switch (error_union.val) { |
| 31442 | .err_name => |err_name| return sema.fail( | 31278 | .err_name => |err_name| return sema.fail( |
| 31443 | block, | 31279 | block, |
| ... | @@ -31452,23 +31288,20 @@ fn beginComptimePtrLoad( | ... | @@ -31452,23 +31288,20 @@ fn beginComptimePtrLoad( |
| 31452 | else => |payload| payload, | 31288 | else => |payload| payload, |
| 31453 | }, | 31289 | }, |
| 31454 | else => unreachable, | 31290 | else => unreachable, |
| 31455 | }), | 31291 | } }, |
| 31292 | .eu_payload, .opt_payload => |p| p.child.*, | ||
| 31293 | else => unreachable, | ||
| 31456 | }; | 31294 | }; |
| 31457 | tv.* = TypedValue{ .ty = payload_ty, .val = payload_val }; | ||
| 31458 | break :blk deref; | 31295 | break :blk deref; |
| 31459 | } | 31296 | } |
| 31460 | } | 31297 | } |
| 31461 | deref.pointee = null; | 31298 | deref.pointee = null; |
| 31462 | break :blk deref; | 31299 | break :blk deref; |
| 31463 | }, | 31300 | }, |
| 31464 | .comptime_field => |comptime_field| blk: { | 31301 | .comptime_field => |field_val| .{ |
| 31465 | const field_ty = Type.fromInterned(ip.typeOf(comptime_field)); | 31302 | .parent = null, |
| 31466 | break :blk ComptimePtrLoadKit{ | 31303 | .pointee = .{ .interned = field_val }, |
| 31467 | .parent = null, | 31304 | .ty_without_well_defined_layout = Type.fromInterned(ip.typeOf(field_val)), |
| 31468 | .pointee = .{ .ty = field_ty, .val = Value.fromInterned(comptime_field) }, | ||
| 31469 | .is_mutable = false, | ||
| 31470 | .ty_without_well_defined_layout = field_ty, | ||
| 31471 | }; | ||
| 31472 | }, | 31305 | }, |
| 31473 | .elem => |elem_ptr| blk: { | 31306 | .elem => |elem_ptr| blk: { |
| 31474 | const elem_ty = Type.fromInterned(ip.typeOf(elem_ptr.base)).elemType2(mod); | 31307 | const elem_ty = Type.fromInterned(ip.typeOf(elem_ptr.base)).elemType2(mod); |
| ... | @@ -31501,30 +31334,37 @@ fn beginComptimePtrLoad( | ... | @@ -31501,30 +31334,37 @@ fn beginComptimePtrLoad( |
| 31501 | 31334 | ||
| 31502 | // If we're loading an elem that was derived from a different type | 31335 | // If we're loading an elem that was derived from a different type |
| 31503 | // than the true type of the underlying decl, we cannot deref directly | 31336 | // than the true type of the underlying decl, we cannot deref directly |
| 31504 | const ty_matches = if (deref.pointee != null and deref.pointee.?.ty.isArrayOrVector(mod)) x: { | 31337 | const ty_matches = if (deref.pointee) |pointee| match: { |
| 31505 | const deref_elem_ty = deref.pointee.?.ty.childType(mod); | 31338 | const ty = pointee.typeOf(mod); |
| 31506 | break :x (try sema.coerceInMemoryAllowed(block, deref_elem_ty, elem_ty, false, target, src, src)) == .ok or | 31339 | if (!ty.isArrayOrVector(mod)) break :match false; |
| 31507 | (try sema.coerceInMemoryAllowed(block, elem_ty, deref_elem_ty, false, target, src, src)) == .ok; | 31340 | const deref_elem_ty = ty.childType(mod); |
| 31341 | if ((try sema.coerceInMemoryAllowed(block, deref_elem_ty, elem_ty, false, target, src, src)) == .ok) break :match true; | ||
| 31342 | if ((try sema.coerceInMemoryAllowed(block, elem_ty, deref_elem_ty, false, target, src, src)) == .ok) break :match true; | ||
| 31343 | break :match false; | ||
| 31508 | } else false; | 31344 | } else false; |
| 31509 | if (!ty_matches) { | 31345 | if (!ty_matches) { |
| 31510 | deref.pointee = null; | 31346 | deref.pointee = null; |
| 31511 | break :blk deref; | 31347 | break :blk deref; |
| 31512 | } | 31348 | } |
| 31513 | 31349 | ||
| 31514 | var array_tv = deref.pointee.?; | 31350 | var array_val = deref.pointee.?; |
| 31515 | const check_len = array_tv.ty.arrayLenIncludingSentinel(mod); | 31351 | const check_len = array_val.typeOf(mod).arrayLenIncludingSentinel(mod); |
| 31516 | if (maybe_array_ty) |load_ty| { | 31352 | if (maybe_array_ty) |load_ty| { |
| 31517 | // It's possible that we're loading a [N]T, in which case we'd like to slice | 31353 | // It's possible that we're loading a [N]T, in which case we'd like to slice |
| 31518 | // the pointee array directly from our parent array. | 31354 | // the pointee array directly from our parent array. |
| 31519 | if (load_ty.isArrayOrVector(mod) and load_ty.childType(mod).eql(elem_ty, mod)) { | 31355 | if (load_ty.isArrayOrVector(mod) and load_ty.childType(mod).eql(elem_ty, mod)) { |
| 31520 | const len = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel(mod)); | 31356 | const len = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel(mod)); |
| 31521 | const elem_idx = try sema.usizeCast(block, src, elem_ptr.index); | 31357 | const elem_idx = try sema.usizeCast(block, src, elem_ptr.index); |
| 31522 | deref.pointee = if (elem_ptr.index + len <= check_len) TypedValue{ | 31358 | deref.pointee = if (elem_ptr.index + len <= check_len) switch (array_val) { |
| 31523 | .ty = try mod.arrayType(.{ | 31359 | .aggregate => |a| .{ .aggregate = .{ |
| 31524 | .len = len, | 31360 | .ty = (try mod.arrayType(.{ .len = len, .child = elem_ty.toIntern() })).toIntern(), |
| 31525 | .child = elem_ty.toIntern(), | 31361 | .elems = a.elems[elem_idx..][0..len], |
| 31526 | }), | 31362 | } }, |
| 31527 | .val = try array_tv.val.sliceArray(sema, elem_idx, elem_idx + len), | 31363 | else => .{ |
| 31364 | .interned = (try (Value.fromInterned( | ||
| 31365 | try array_val.intern(mod, sema.arena), | ||
| 31366 | ).sliceArray(sema, elem_idx, elem_idx + len))).toIntern(), | ||
| 31367 | }, | ||
| 31528 | } else null; | 31368 | } else null; |
| 31529 | break :blk deref; | 31369 | break :blk deref; |
| 31530 | } | 31370 | } |
| ... | @@ -31535,18 +31375,12 @@ fn beginComptimePtrLoad( | ... | @@ -31535,18 +31375,12 @@ fn beginComptimePtrLoad( |
| 31535 | break :blk deref; | 31375 | break :blk deref; |
| 31536 | } | 31376 | } |
| 31537 | if (elem_ptr.index == check_len - 1) { | 31377 | if (elem_ptr.index == check_len - 1) { |
| 31538 | if (array_tv.ty.sentinel(mod)) |sent| { | 31378 | if (array_val.typeOf(mod).sentinel(mod)) |sent| { |
| 31539 | deref.pointee = TypedValue{ | 31379 | deref.pointee = .{ .interned = sent.toIntern() }; |
| 31540 | .ty = elem_ty, | ||
| 31541 | .val = sent, | ||
| 31542 | }; | ||
| 31543 | break :blk deref; | 31380 | break :blk deref; |
| 31544 | } | 31381 | } |
| 31545 | } | 31382 | } |
| 31546 | deref.pointee = TypedValue{ | 31383 | deref.pointee = try array_val.getElem(mod, @intCast(elem_ptr.index)); |
| 31547 | .ty = elem_ty, | ||
| 31548 | .val = try array_tv.val.elemValue(mod, @intCast(elem_ptr.index)), | ||
| 31549 | }; | ||
| 31550 | break :blk deref; | 31384 | break :blk deref; |
| 31551 | }, | 31385 | }, |
| 31552 | .field => |field_ptr| blk: { | 31386 | .field => |field_ptr| blk: { |
| ... | @@ -31570,37 +31404,17 @@ fn beginComptimePtrLoad( | ... | @@ -31570,37 +31404,17 @@ fn beginComptimePtrLoad( |
| 31570 | deref.ty_without_well_defined_layout = container_ty; | 31404 | deref.ty_without_well_defined_layout = container_ty; |
| 31571 | } | 31405 | } |
| 31572 | 31406 | ||
| 31573 | const tv = deref.pointee orelse { | 31407 | const pointee = deref.pointee orelse break :blk deref; |
| 31574 | deref.pointee = null; | 31408 | const pointee_ty = pointee.typeOf(mod); |
| 31575 | break :blk deref; | ||
| 31576 | }; | ||
| 31577 | const coerce_in_mem_ok = | 31409 | const coerce_in_mem_ok = |
| 31578 | (try sema.coerceInMemoryAllowed(block, container_ty, tv.ty, false, target, src, src)) == .ok or | 31410 | (try sema.coerceInMemoryAllowed(block, container_ty, pointee_ty, false, target, src, src)) == .ok or |
| 31579 | (try sema.coerceInMemoryAllowed(block, tv.ty, container_ty, false, target, src, src)) == .ok; | 31411 | (try sema.coerceInMemoryAllowed(block, pointee_ty, container_ty, false, target, src, src)) == .ok; |
| 31580 | if (!coerce_in_mem_ok) { | 31412 | if (!coerce_in_mem_ok) { |
| 31581 | deref.pointee = null; | 31413 | deref.pointee = null; |
| 31582 | break :blk deref; | 31414 | break :blk deref; |
| 31583 | } | 31415 | } |
| 31584 | 31416 | ||
| 31585 | if (container_ty.isSlice(mod)) { | 31417 | deref.pointee = try pointee.getElem(mod, field_index); |
| 31586 | deref.pointee = switch (field_index) { | ||
| 31587 | Value.slice_ptr_index => TypedValue{ | ||
| 31588 | .ty = container_ty.slicePtrFieldType(mod), | ||
| 31589 | .val = tv.val.slicePtr(mod), | ||
| 31590 | }, | ||
| 31591 | Value.slice_len_index => TypedValue{ | ||
| 31592 | .ty = Type.usize, | ||
| 31593 | .val = Value.fromInterned(ip.indexToKey(try tv.val.intern(tv.ty, mod)).slice.len), | ||
| 31594 | }, | ||
| 31595 | else => unreachable, | ||
| 31596 | }; | ||
| 31597 | } else { | ||
| 31598 | const field_ty = container_ty.structFieldType(field_index, mod); | ||
| 31599 | deref.pointee = TypedValue{ | ||
| 31600 | .ty = field_ty, | ||
| 31601 | .val = try tv.val.fieldValue(mod, field_index), | ||
| 31602 | }; | ||
| 31603 | } | ||
| 31604 | break :blk deref; | 31418 | break :blk deref; |
| 31605 | }, | 31419 | }, |
| 31606 | }, | 31420 | }, |
| ... | @@ -31611,9 +31425,9 @@ fn beginComptimePtrLoad( | ... | @@ -31611,9 +31425,9 @@ fn beginComptimePtrLoad( |
| 31611 | else => unreachable, | 31425 | else => unreachable, |
| 31612 | }; | 31426 | }; |
| 31613 | 31427 | ||
| 31614 | if (deref.pointee) |tv| { | 31428 | if (deref.pointee) |val| { |
| 31615 | if (deref.parent == null and tv.ty.hasWellDefinedLayout(mod)) { | 31429 | if (deref.parent == null and val.typeOf(mod).hasWellDefinedLayout(mod)) { |
| 31616 | deref.parent = .{ .tv = tv, .byte_offset = 0 }; | 31430 | deref.parent = .{ .val = val, .byte_offset = 0 }; |
| 31617 | } | 31431 | } |
| 31618 | } | 31432 | } |
| 31619 | return deref; | 31433 | return deref; |
| ... | @@ -31760,16 +31574,11 @@ fn coerceArrayPtrToSlice( | ... | @@ -31760,16 +31574,11 @@ fn coerceArrayPtrToSlice( |
| 31760 | if (try sema.resolveValue(inst)) |val| { | 31574 | if (try sema.resolveValue(inst)) |val| { |
| 31761 | const ptr_array_ty = sema.typeOf(inst); | 31575 | const ptr_array_ty = sema.typeOf(inst); |
| 31762 | const array_ty = ptr_array_ty.childType(mod); | 31576 | const array_ty = ptr_array_ty.childType(mod); |
| 31577 | const slice_ptr_ty = dest_ty.slicePtrFieldType(mod); | ||
| 31578 | const slice_ptr = try mod.getCoerced(val, slice_ptr_ty); | ||
| 31763 | const slice_val = try mod.intern(.{ .slice = .{ | 31579 | const slice_val = try mod.intern(.{ .slice = .{ |
| 31764 | .ty = dest_ty.toIntern(), | 31580 | .ty = dest_ty.toIntern(), |
| 31765 | .ptr = try mod.intern(.{ .ptr = .{ | 31581 | .ptr = slice_ptr.toIntern(), |
| 31766 | .ty = dest_ty.slicePtrFieldType(mod).toIntern(), | ||
| 31767 | .addr = switch (mod.intern_pool.indexToKey(val.toIntern())) { | ||
| 31768 | .undef => .{ .int = try mod.intern(.{ .undef = .usize_type }) }, | ||
| 31769 | .ptr => |ptr| ptr.addr, | ||
| 31770 | else => unreachable, | ||
| 31771 | }, | ||
| 31772 | } }), | ||
| 31773 | .len = (try mod.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(), | 31582 | .len = (try mod.intValue(Type.usize, array_ty.arrayLen(mod))).toIntern(), |
| 31774 | } }); | 31583 | } }); |
| 31775 | return Air.internedToRef(slice_val); | 31584 | return Air.internedToRef(slice_val); |
| ... | @@ -31844,7 +31653,7 @@ fn coerceCompatiblePtrs( | ... | @@ -31844,7 +31653,7 @@ fn coerceCompatiblePtrs( |
| 31844 | } | 31653 | } |
| 31845 | // The comptime Value representation is compatible with both types. | 31654 | // The comptime Value representation is compatible with both types. |
| 31846 | return Air.internedToRef( | 31655 | return Air.internedToRef( |
| 31847 | (try mod.getCoerced(Value.fromInterned((try val.intern(inst_ty, mod))), dest_ty)).toIntern(), | 31656 | (try mod.getCoerced(val, dest_ty)).toIntern(), |
| 31848 | ); | 31657 | ); |
| 31849 | } | 31658 | } |
| 31850 | try sema.requireRuntimeBlock(block, inst_src, null); | 31659 | try sema.requireRuntimeBlock(block, inst_src, null); |
| ... | @@ -31899,7 +31708,7 @@ fn coerceEnumToUnion( | ... | @@ -31899,7 +31708,7 @@ fn coerceEnumToUnion( |
| 31899 | if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| { | 31708 | if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| { |
| 31900 | const field_index = union_ty.unionTagFieldIndex(val, sema.mod) orelse { | 31709 | const field_index = union_ty.unionTagFieldIndex(val, sema.mod) orelse { |
| 31901 | return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{ | 31710 | return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{ |
| 31902 | union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod), | 31711 | union_ty.fmt(sema.mod), val.fmtValue(sema.mod), |
| 31903 | }); | 31712 | }); |
| 31904 | }; | 31713 | }; |
| 31905 | 31714 | ||
| ... | @@ -32181,7 +31990,7 @@ fn coerceArrayLike( | ... | @@ -32181,7 +31990,7 @@ fn coerceArrayLike( |
| 32181 | ref.* = coerced; | 31990 | ref.* = coerced; |
| 32182 | if (runtime_src == null) { | 31991 | if (runtime_src == null) { |
| 32183 | if (try sema.resolveValue(coerced)) |elem_val| { | 31992 | if (try sema.resolveValue(coerced)) |elem_val| { |
| 32184 | val.* = try elem_val.intern(dest_elem_ty, mod); | 31993 | val.* = elem_val.toIntern(); |
| 32185 | } else { | 31994 | } else { |
| 32186 | runtime_src = elem_src; | 31995 | runtime_src = elem_src; |
| 32187 | } | 31996 | } |
| ... | @@ -32246,7 +32055,7 @@ fn coerceTupleToArray( | ... | @@ -32246,7 +32055,7 @@ fn coerceTupleToArray( |
| 32246 | ref.* = coerced; | 32055 | ref.* = coerced; |
| 32247 | if (runtime_src == null) { | 32056 | if (runtime_src == null) { |
| 32248 | if (try sema.resolveValue(coerced)) |elem_val| { | 32057 | if (try sema.resolveValue(coerced)) |elem_val| { |
| 32249 | val.* = try elem_val.intern(dest_elem_ty, mod); | 32058 | val.* = elem_val.toIntern(); |
| 32250 | } else { | 32059 | } else { |
| 32251 | runtime_src = elem_src; | 32060 | runtime_src = elem_src; |
| 32252 | } | 32061 | } |
| ... | @@ -32650,7 +32459,7 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value { | ... | @@ -32650,7 +32459,7 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value { |
| 32650 | return Value.fromInterned((try mod.intern(.{ .opt = .{ | 32459 | return Value.fromInterned((try mod.intern(.{ .opt = .{ |
| 32651 | .ty = (try mod.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(), | 32460 | .ty = (try mod.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(), |
| 32652 | .val = if (opt_val) |val| (try mod.getCoerced( | 32461 | .val = if (opt_val) |val| (try mod.getCoerced( |
| 32653 | Value.fromInterned((try sema.refValue(val.toIntern()))), | 32462 | Value.fromInterned(try sema.refValue(val.toIntern())), |
| 32654 | ptr_anyopaque_ty, | 32463 | ptr_anyopaque_ty, |
| 32655 | )).toIntern() else .none, | 32464 | )).toIntern() else .none, |
| 32656 | } }))); | 32465 | } }))); |
| ... | @@ -32668,8 +32477,8 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: InternPool.DeclIndex, analyze_fn | ... | @@ -32668,8 +32477,8 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: InternPool.DeclIndex, analyze_fn |
| 32668 | const mod = sema.mod; | 32477 | const mod = sema.mod; |
| 32669 | try sema.ensureDeclAnalyzed(decl_index); | 32478 | try sema.ensureDeclAnalyzed(decl_index); |
| 32670 | 32479 | ||
| 32671 | const decl_tv = try mod.declPtr(decl_index).typedValue(); | 32480 | const decl_val = try mod.declPtr(decl_index).valueOrFail(); |
| 32672 | const owner_decl = mod.declPtr(switch (mod.intern_pool.indexToKey(decl_tv.val.toIntern())) { | 32481 | const owner_decl = mod.declPtr(switch (mod.intern_pool.indexToKey(decl_val.toIntern())) { |
| 32673 | .variable => |variable| variable.decl, | 32482 | .variable => |variable| variable.decl, |
| 32674 | .extern_func => |extern_func| extern_func.decl, | 32483 | .extern_func => |extern_func| extern_func.decl, |
| 32675 | .func => |func| func.owner_decl, | 32484 | .func => |func| func.owner_decl, |
| ... | @@ -32678,10 +32487,10 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: InternPool.DeclIndex, analyze_fn | ... | @@ -32678,10 +32487,10 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: InternPool.DeclIndex, analyze_fn |
| 32678 | // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type | 32487 | // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type |
| 32679 | try sema.declareDependency(.{ .decl_val = decl_index }); | 32488 | try sema.declareDependency(.{ .decl_val = decl_index }); |
| 32680 | const ptr_ty = try sema.ptrType(.{ | 32489 | const ptr_ty = try sema.ptrType(.{ |
| 32681 | .child = decl_tv.ty.toIntern(), | 32490 | .child = decl_val.typeOf(mod).toIntern(), |
| 32682 | .flags = .{ | 32491 | .flags = .{ |
| 32683 | .alignment = owner_decl.alignment, | 32492 | .alignment = owner_decl.alignment, |
| 32684 | .is_const = if (decl_tv.val.getVariable(mod)) |variable| variable.is_const else true, | 32493 | .is_const = if (decl_val.getVariable(mod)) |variable| variable.is_const else true, |
| 32685 | .address_space = owner_decl.@"addrspace", | 32494 | .address_space = owner_decl.@"addrspace", |
| 32686 | }, | 32495 | }, |
| 32687 | }); | 32496 | }); |
| ... | @@ -32697,12 +32506,10 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: InternPool.DeclIndex, analyze_fn | ... | @@ -32697,12 +32506,10 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: InternPool.DeclIndex, analyze_fn |
| 32697 | fn maybeQueueFuncBodyAnalysis(sema: *Sema, decl_index: InternPool.DeclIndex) !void { | 32506 | fn maybeQueueFuncBodyAnalysis(sema: *Sema, decl_index: InternPool.DeclIndex) !void { |
| 32698 | const mod = sema.mod; | 32507 | const mod = sema.mod; |
| 32699 | const decl = mod.declPtr(decl_index); | 32508 | const decl = mod.declPtr(decl_index); |
| 32700 | const tv = try decl.typedValue(); | 32509 | const decl_val = try decl.valueOrFail(); |
| 32701 | if (tv.ty.zigTypeTag(mod) != .Fn) return; | 32510 | if (!mod.intern_pool.isFuncBody(decl_val.toIntern())) return; |
| 32702 | if (!try sema.fnHasRuntimeBits(tv.ty)) return; | 32511 | if (!try sema.fnHasRuntimeBits(decl_val.typeOf(mod))) return; |
| 32703 | const func_index = tv.val.toIntern(); | 32512 | try mod.ensureFuncBodyAnalysisQueued(decl_val.toIntern()); |
| 32704 | if (!mod.intern_pool.isFuncBody(func_index)) return; // undef or extern function | ||
| 32705 | try mod.ensureFuncBodyAnalysisQueued(func_index); | ||
| 32706 | } | 32513 | } |
| 32707 | 32514 | ||
| 32708 | fn analyzeRef( | 32515 | fn analyzeRef( |
| ... | @@ -32839,7 +32646,7 @@ fn analyzeSliceLen( | ... | @@ -32839,7 +32646,7 @@ fn analyzeSliceLen( |
| 32839 | if (slice_val.isUndef(mod)) { | 32646 | if (slice_val.isUndef(mod)) { |
| 32840 | return mod.undefRef(Type.usize); | 32647 | return mod.undefRef(Type.usize); |
| 32841 | } | 32648 | } |
| 32842 | return mod.intRef(Type.usize, slice_val.sliceLen(sema.mod)); | 32649 | return mod.intRef(Type.usize, try slice_val.sliceLen(sema)); |
| 32843 | } | 32650 | } |
| 32844 | try sema.requireRuntimeBlock(block, src, null); | 32651 | try sema.requireRuntimeBlock(block, src, null); |
| 32845 | return block.addTyOp(.slice_len, Type.usize, slice_inst); | 32652 | return block.addTyOp(.slice_len, Type.usize, slice_inst); |
| ... | @@ -33121,8 +32928,8 @@ fn analyzeSlice( | ... | @@ -33121,8 +32928,8 @@ fn analyzeSlice( |
| 33121 | msg, | 32928 | msg, |
| 33122 | "expected '{}', found '{}'", | 32929 | "expected '{}', found '{}'", |
| 33123 | .{ | 32930 | .{ |
| 33124 | Value.zero_comptime_int.fmtValue(Type.comptime_int, mod), | 32931 | Value.zero_comptime_int.fmtValue(mod), |
| 33125 | start_value.fmtValue(Type.comptime_int, mod), | 32932 | start_value.fmtValue(mod), |
| 33126 | }, | 32933 | }, |
| 33127 | ); | 32934 | ); |
| 33128 | break :msg msg; | 32935 | break :msg msg; |
| ... | @@ -33138,8 +32945,8 @@ fn analyzeSlice( | ... | @@ -33138,8 +32945,8 @@ fn analyzeSlice( |
| 33138 | msg, | 32945 | msg, |
| 33139 | "expected '{}', found '{}'", | 32946 | "expected '{}', found '{}'", |
| 33140 | .{ | 32947 | .{ |
| 33141 | Value.one_comptime_int.fmtValue(Type.comptime_int, mod), | 32948 | Value.one_comptime_int.fmtValue(mod), |
| 33142 | end_value.fmtValue(Type.comptime_int, mod), | 32949 | end_value.fmtValue(mod), |
| 33143 | }, | 32950 | }, |
| 33144 | ); | 32951 | ); |
| 33145 | break :msg msg; | 32952 | break :msg msg; |
| ... | @@ -33152,7 +32959,7 @@ fn analyzeSlice( | ... | @@ -33152,7 +32959,7 @@ fn analyzeSlice( |
| 33152 | block, | 32959 | block, |
| 33153 | end_src, | 32960 | end_src, |
| 33154 | "end index {} out of bounds for slice of single-item pointer", | 32961 | "end index {} out of bounds for slice of single-item pointer", |
| 33155 | .{end_value.fmtValue(Type.comptime_int, mod)}, | 32962 | .{end_value.fmtValue(mod)}, |
| 33156 | ); | 32963 | ); |
| 33157 | } | 32964 | } |
| 33158 | } | 32965 | } |
| ... | @@ -33247,8 +33054,8 @@ fn analyzeSlice( | ... | @@ -33247,8 +33054,8 @@ fn analyzeSlice( |
| 33247 | end_src, | 33054 | end_src, |
| 33248 | "end index {} out of bounds for array of length {}{s}", | 33055 | "end index {} out of bounds for array of length {}{s}", |
| 33249 | .{ | 33056 | .{ |
| 33250 | end_val.fmtValue(Type.usize, mod), | 33057 | end_val.fmtValue(mod), |
| 33251 | len_val.fmtValue(Type.usize, mod), | 33058 | len_val.fmtValue(mod), |
| 33252 | sentinel_label, | 33059 | sentinel_label, |
| 33253 | }, | 33060 | }, |
| 33254 | ); | 33061 | ); |
| ... | @@ -33278,7 +33085,7 @@ fn analyzeSlice( | ... | @@ -33278,7 +33085,7 @@ fn analyzeSlice( |
| 33278 | return sema.fail(block, src, "slice of undefined", .{}); | 33085 | return sema.fail(block, src, "slice of undefined", .{}); |
| 33279 | } | 33086 | } |
| 33280 | const has_sentinel = slice_ty.sentinel(mod) != null; | 33087 | const has_sentinel = slice_ty.sentinel(mod) != null; |
| 33281 | const slice_len = slice_val.sliceLen(mod); | 33088 | const slice_len = try slice_val.sliceLen(sema); |
| 33282 | const len_plus_sent = slice_len + @intFromBool(has_sentinel); | 33089 | const len_plus_sent = slice_len + @intFromBool(has_sentinel); |
| 33283 | const slice_len_val_with_sentinel = try mod.intValue(Type.usize, len_plus_sent); | 33090 | const slice_len_val_with_sentinel = try mod.intValue(Type.usize, len_plus_sent); |
| 33284 | if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, Type.usize))) { | 33091 | if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, Type.usize))) { |
| ... | @@ -33292,8 +33099,8 @@ fn analyzeSlice( | ... | @@ -33292,8 +33099,8 @@ fn analyzeSlice( |
| 33292 | end_src, | 33099 | end_src, |
| 33293 | "end index {} out of bounds for slice of length {d}{s}", | 33100 | "end index {} out of bounds for slice of length {d}{s}", |
| 33294 | .{ | 33101 | .{ |
| 33295 | end_val.fmtValue(Type.usize, mod), | 33102 | end_val.fmtValue(mod), |
| 33296 | slice_val.sliceLen(mod), | 33103 | try slice_val.sliceLen(sema), |
| 33297 | sentinel_label, | 33104 | sentinel_label, |
| 33298 | }, | 33105 | }, |
| 33299 | ); | 33106 | ); |
| ... | @@ -33352,8 +33159,8 @@ fn analyzeSlice( | ... | @@ -33352,8 +33159,8 @@ fn analyzeSlice( |
| 33352 | start_src, | 33159 | start_src, |
| 33353 | "start index {} is larger than end index {}", | 33160 | "start index {} is larger than end index {}", |
| 33354 | .{ | 33161 | .{ |
| 33355 | start_val.fmtValue(Type.usize, mod), | 33162 | start_val.fmtValue(mod), |
| 33356 | end_val.fmtValue(Type.usize, mod), | 33163 | end_val.fmtValue(mod), |
| 33357 | }, | 33164 | }, |
| 33358 | ); | 33165 | ); |
| 33359 | } | 33166 | } |
| ... | @@ -33391,8 +33198,8 @@ fn analyzeSlice( | ... | @@ -33391,8 +33198,8 @@ fn analyzeSlice( |
| 33391 | const msg = try sema.errMsg(block, src, "value in memory does not match slice sentinel", .{}); | 33198 | const msg = try sema.errMsg(block, src, "value in memory does not match slice sentinel", .{}); |
| 33392 | errdefer msg.destroy(sema.gpa); | 33199 | errdefer msg.destroy(sema.gpa); |
| 33393 | try sema.errNote(block, src, msg, "expected '{}', found '{}'", .{ | 33200 | try sema.errNote(block, src, msg, "expected '{}', found '{}'", .{ |
| 33394 | expected_sentinel.fmtValue(elem_ty, mod), | 33201 | expected_sentinel.fmtValue(mod), |
| 33395 | actual_sentinel.fmtValue(elem_ty, mod), | 33202 | actual_sentinel.fmtValue(mod), |
| 33396 | }); | 33203 | }); |
| 33397 | 33204 | ||
| 33398 | break :msg msg; | 33205 | break :msg msg; |
| ... | @@ -33483,10 +33290,7 @@ fn analyzeSlice( | ... | @@ -33483,10 +33290,7 @@ fn analyzeSlice( |
| 33483 | }; | 33290 | }; |
| 33484 | 33291 | ||
| 33485 | if (!new_ptr_val.isUndef(mod)) { | 33292 | if (!new_ptr_val.isUndef(mod)) { |
| 33486 | return Air.internedToRef((try mod.getCoerced( | 33293 | return Air.internedToRef((try mod.getCoerced(new_ptr_val, return_ty)).toIntern()); |
| 33487 | Value.fromInterned((try new_ptr_val.intern(new_ptr_ty, mod))), | ||
| 33488 | return_ty, | ||
| 33489 | )).toIntern()); | ||
| 33490 | } | 33294 | } |
| 33491 | 33295 | ||
| 33492 | // Special case: @as([]i32, undefined)[x..x] | 33296 | // Special case: @as([]i32, undefined)[x..x] |
| ... | @@ -33525,7 +33329,7 @@ fn analyzeSlice( | ... | @@ -33525,7 +33329,7 @@ fn analyzeSlice( |
| 33525 | if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| { | 33329 | if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| { |
| 33526 | // we don't need to add one for sentinels because the | 33330 | // we don't need to add one for sentinels because the |
| 33527 | // underlying value data includes the sentinel | 33331 | // underlying value data includes the sentinel |
| 33528 | break :blk try mod.intRef(Type.usize, slice_val.sliceLen(mod)); | 33332 | break :blk try mod.intRef(Type.usize, try slice_val.sliceLen(sema)); |
| 33529 | } | 33333 | } |
| 33530 | 33334 | ||
| 33531 | const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice); | 33335 | const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice); |
| ... | @@ -33998,7 +33802,7 @@ fn wrapErrorUnionPayload( | ... | @@ -33998,7 +33802,7 @@ fn wrapErrorUnionPayload( |
| 33998 | if (try sema.resolveValue(coerced)) |val| { | 33802 | if (try sema.resolveValue(coerced)) |val| { |
| 33999 | return Air.internedToRef((try mod.intern(.{ .error_union = .{ | 33803 | return Air.internedToRef((try mod.intern(.{ .error_union = .{ |
| 34000 | .ty = dest_ty.toIntern(), | 33804 | .ty = dest_ty.toIntern(), |
| 34001 | .val = .{ .payload = try val.intern(dest_payload_ty, mod) }, | 33805 | .val = .{ .payload = val.toIntern() }, |
| 34002 | } }))); | 33806 | } }))); |
| 34003 | } | 33807 | } |
| 34004 | try sema.requireRuntimeBlock(block, inst_src, null); | 33808 | try sema.requireRuntimeBlock(block, inst_src, null); |
| ... | @@ -36611,7 +36415,7 @@ fn resolveInferredErrorSet( | ... | @@ -36611,7 +36415,7 @@ fn resolveInferredErrorSet( |
| 36611 | // inferred error sets, each call gets an adhoc InferredErrorSet object, which | 36415 | // inferred error sets, each call gets an adhoc InferredErrorSet object, which |
| 36612 | // has no corresponding function body. | 36416 | // has no corresponding function body. |
| 36613 | const ies_func_owner_decl = mod.declPtr(func.owner_decl); | 36417 | const ies_func_owner_decl = mod.declPtr(func.owner_decl); |
| 36614 | const ies_func_info = mod.typeToFunc(ies_func_owner_decl.ty).?; | 36418 | const ies_func_info = mod.typeToFunc(ies_func_owner_decl.typeOf(mod)).?; |
| 36615 | // if ies declared by a inline function with generic return type, the return_type should be generic_poison, | 36419 | // if ies declared by a inline function with generic return type, the return_type should be generic_poison, |
| 36616 | // because inline function does not create a new declaration, and the ies has been filled with analyzeCall, | 36420 | // because inline function does not create a new declaration, and the ies has been filled with analyzeCall, |
| 36617 | // so here we can simply skip this case. | 36421 | // so here we can simply skip this case. |
| ... | @@ -37174,15 +36978,14 @@ fn semaStructFieldInits( | ... | @@ -37174,15 +36978,14 @@ fn semaStructFieldInits( |
| 37174 | }); | 36978 | }); |
| 37175 | }; | 36979 | }; |
| 37176 | 36980 | ||
| 37177 | const field_init = try default_val.intern(field_ty, mod); | 36981 | if (default_val.canMutateComptimeVarState(mod)) { |
| 37178 | if (Value.fromInterned(field_init).canMutateComptimeVarState(mod)) { | ||
| 37179 | const init_src = mod.fieldSrcLoc(decl_index, .{ | 36982 | const init_src = mod.fieldSrcLoc(decl_index, .{ |
| 37180 | .index = field_i, | 36983 | .index = field_i, |
| 37181 | .range = .value, | 36984 | .range = .value, |
| 37182 | }).lazy; | 36985 | }).lazy; |
| 37183 | return sema.fail(&block_scope, init_src, "field default value contains reference to comptime-mutable memory", .{}); | 36986 | return sema.fail(&block_scope, init_src, "field default value contains reference to comptime-mutable memory", .{}); |
| 37184 | } | 36987 | } |
| 37185 | struct_type.field_inits.get(ip)[field_i] = field_init; | 36988 | struct_type.field_inits.get(ip)[field_i] = default_val.toIntern(); |
| 37186 | } | 36989 | } |
| 37187 | } | 36990 | } |
| 37188 | } | 36991 | } |
| ... | @@ -37410,7 +37213,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded | ... | @@ -37410,7 +37213,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded |
| 37410 | const field_src = mod.fieldSrcLoc(union_type.decl, .{ .index = field_i }).lazy; | 37213 | const field_src = mod.fieldSrcLoc(union_type.decl, .{ .index = field_i }).lazy; |
| 37411 | const other_field_src = mod.fieldSrcLoc(union_type.decl, .{ .index = gop.index }).lazy; | 37214 | const other_field_src = mod.fieldSrcLoc(union_type.decl, .{ .index = gop.index }).lazy; |
| 37412 | const msg = msg: { | 37215 | const msg = msg: { |
| 37413 | const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(int_tag_ty, mod)}); | 37216 | const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(mod)}); |
| 37414 | errdefer msg.destroy(gpa); | 37217 | errdefer msg.destroy(gpa); |
| 37415 | try sema.errNote(&block_scope, other_field_src, msg, "other occurrence here", .{}); | 37218 | try sema.errNote(&block_scope, other_field_src, msg, "other occurrence here", .{}); |
| 37416 | break :msg msg; | 37219 | break :msg msg; |
| ... | @@ -37607,10 +37410,12 @@ fn generateUnionTagTypeNumbered( | ... | @@ -37607,10 +37410,12 @@ fn generateUnionTagTypeNumbered( |
| 37607 | errdefer mod.destroyDecl(new_decl_index); | 37410 | errdefer mod.destroyDecl(new_decl_index); |
| 37608 | const fqn = try union_owner_decl.fullyQualifiedName(mod); | 37411 | const fqn = try union_owner_decl.fullyQualifiedName(mod); |
| 37609 | const name = try ip.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(ip)}); | 37412 | const name = try ip.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(ip)}); |
| 37610 | try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, .{ | 37413 | try mod.initNewAnonDecl( |
| 37611 | .ty = Type.noreturn, | 37414 | new_decl_index, |
| 37612 | .val = Value.@"unreachable", | 37415 | src_decl.src_line, |
| 37613 | }, name); | 37416 | Value.@"unreachable", |
| 37417 | name, | ||
| 37418 | ); | ||
| 37614 | errdefer mod.abortAnonDecl(new_decl_index); | 37419 | errdefer mod.abortAnonDecl(new_decl_index); |
| 37615 | 37420 | ||
| 37616 | const new_decl = mod.declPtr(new_decl_index); | 37421 | const new_decl = mod.declPtr(new_decl_index); |
| ... | @@ -37629,7 +37434,6 @@ fn generateUnionTagTypeNumbered( | ... | @@ -37629,7 +37434,6 @@ fn generateUnionTagTypeNumbered( |
| 37629 | .tag_mode = .explicit, | 37434 | .tag_mode = .explicit, |
| 37630 | }); | 37435 | }); |
| 37631 | 37436 | ||
| 37632 | new_decl.ty = Type.type; | ||
| 37633 | new_decl.val = Value.fromInterned(enum_ty); | 37437 | new_decl.val = Value.fromInterned(enum_ty); |
| 37634 | 37438 | ||
| 37635 | try mod.finalizeAnonDecl(new_decl_index); | 37439 | try mod.finalizeAnonDecl(new_decl_index); |
| ... | @@ -37652,10 +37456,12 @@ fn generateUnionTagTypeSimple( | ... | @@ -37652,10 +37456,12 @@ fn generateUnionTagTypeSimple( |
| 37652 | const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node); | 37456 | const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node); |
| 37653 | errdefer mod.destroyDecl(new_decl_index); | 37457 | errdefer mod.destroyDecl(new_decl_index); |
| 37654 | const name = try ip.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(ip)}); | 37458 | const name = try ip.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(ip)}); |
| 37655 | try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, .{ | 37459 | try mod.initNewAnonDecl( |
| 37656 | .ty = Type.noreturn, | 37460 | new_decl_index, |
| 37657 | .val = Value.@"unreachable", | 37461 | src_decl.src_line, |
| 37658 | }, name); | 37462 | Value.@"unreachable", |
| 37463 | name, | ||
| 37464 | ); | ||
| 37659 | mod.declPtr(new_decl_index).name_fully_qualified = true; | 37465 | mod.declPtr(new_decl_index).name_fully_qualified = true; |
| 37660 | break :new_decl_index new_decl_index; | 37466 | break :new_decl_index new_decl_index; |
| 37661 | }; | 37467 | }; |
| ... | @@ -37675,7 +37481,6 @@ fn generateUnionTagTypeSimple( | ... | @@ -37675,7 +37481,6 @@ fn generateUnionTagTypeSimple( |
| 37675 | 37481 | ||
| 37676 | const new_decl = mod.declPtr(new_decl_index); | 37482 | const new_decl = mod.declPtr(new_decl_index); |
| 37677 | new_decl.owns_tv = true; | 37483 | new_decl.owns_tv = true; |
| 37678 | new_decl.ty = Type.type; | ||
| 37679 | new_decl.val = Value.fromInterned(enum_ty); | 37484 | new_decl.val = Value.fromInterned(enum_ty); |
| 37680 | 37485 | ||
| 37681 | try mod.finalizeAnonDecl(new_decl_index); | 37486 | try mod.finalizeAnonDecl(new_decl_index); |
| ... | @@ -37991,7 +37796,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -37991,7 +37796,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 37991 | return sema.failWithOwnedErrorMsg(null, msg); | 37796 | return sema.failWithOwnedErrorMsg(null, msg); |
| 37992 | } | 37797 | } |
| 37993 | if (try sema.typeHasOnePossibleValue(field_ty)) |field_opv| { | 37798 | if (try sema.typeHasOnePossibleValue(field_ty)) |field_opv| { |
| 37994 | field_val.* = try field_opv.intern(field_ty, mod); | 37799 | field_val.* = field_opv.toIntern(); |
| 37995 | } else return null; | 37800 | } else return null; |
| 37996 | } | 37801 | } |
| 37997 | 37802 | ||
| ... | @@ -38290,17 +38095,18 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value | ... | @@ -38290,17 +38095,18 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value |
| 38290 | else => |e| return e, | 38095 | else => |e| return e, |
| 38291 | }; | 38096 | }; |
| 38292 | 38097 | ||
| 38293 | if (deref.pointee) |tv| { | 38098 | if (deref.pointee) |pointee| { |
| 38099 | const uncoerced_val = Value.fromInterned(try pointee.intern(mod, sema.arena)); | ||
| 38100 | const ty = Type.fromInterned(mod.intern_pool.typeOf(uncoerced_val.toIntern())); | ||
| 38294 | const coerce_in_mem_ok = | 38101 | const coerce_in_mem_ok = |
| 38295 | (try sema.coerceInMemoryAllowed(block, load_ty, tv.ty, false, target, src, src)) == .ok or | 38102 | (try sema.coerceInMemoryAllowed(block, load_ty, ty, false, target, src, src)) == .ok or |
| 38296 | (try sema.coerceInMemoryAllowed(block, tv.ty, load_ty, false, target, src, src)) == .ok; | 38103 | (try sema.coerceInMemoryAllowed(block, ty, load_ty, false, target, src, src)) == .ok; |
| 38297 | if (coerce_in_mem_ok) { | 38104 | if (coerce_in_mem_ok) { |
| 38298 | // We have a Value that lines up in virtual memory exactly with what we want to load, | 38105 | // We have a Value that lines up in virtual memory exactly with what we want to load, |
| 38299 | // and it is in-memory coercible to load_ty. It may be returned without modifications. | 38106 | // and it is in-memory coercible to load_ty. It may be returned without modifications. |
| 38300 | // Move mutable decl values to the InternPool and assert other decls are already in | 38107 | // Move mutable decl values to the InternPool and assert other decls are already in |
| 38301 | // the InternPool. | 38108 | // the InternPool. |
| 38302 | const uncoerced_val = if (deref.is_mutable) try tv.val.intern(tv.ty, mod) else tv.val.toIntern(); | 38109 | const coerced_val = try mod.getCoerced(uncoerced_val, load_ty); |
| 38303 | const coerced_val = try mod.getCoerced(Value.fromInterned(uncoerced_val), load_ty); | ||
| 38304 | return .{ .val = coerced_val }; | 38110 | return .{ .val = coerced_val }; |
| 38305 | } | 38111 | } |
| 38306 | } | 38112 | } |
| ... | @@ -38314,21 +38120,35 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value | ... | @@ -38314,21 +38120,35 @@ fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value |
| 38314 | const load_sz = try sema.typeAbiSize(load_ty); | 38120 | const load_sz = try sema.typeAbiSize(load_ty); |
| 38315 | 38121 | ||
| 38316 | // Try the smaller bit-cast first, since that's more efficient than using the larger `parent` | 38122 | // Try the smaller bit-cast first, since that's more efficient than using the larger `parent` |
| 38317 | if (deref.pointee) |tv| if (load_sz <= try sema.typeAbiSize(tv.ty)) | 38123 | if (deref.pointee) |pointee| { |
| 38318 | return DerefResult{ .val = (try sema.bitCastVal(block, src, tv.val, tv.ty, load_ty, 0)) orelse return .runtime_load }; | 38124 | const val_ip_index = try pointee.intern(mod, sema.arena); |
| 38125 | const val = Value.fromInterned(val_ip_index); | ||
| 38126 | const ty = Type.fromInterned(mod.intern_pool.typeOf(val_ip_index)); | ||
| 38127 | if (load_sz <= try sema.typeAbiSize(ty)) { | ||
| 38128 | return .{ .val = (try sema.bitCastVal(block, src, val, ty, load_ty, 0)) orelse return .runtime_load }; | ||
| 38129 | } | ||
| 38130 | } | ||
| 38319 | 38131 | ||
| 38320 | // If that fails, try to bit-cast from the largest parent value with a well-defined layout | 38132 | // If that fails, try to bit-cast from the largest parent value with a well-defined layout |
| 38321 | if (deref.parent) |parent| if (load_sz + parent.byte_offset <= try sema.typeAbiSize(parent.tv.ty)) | 38133 | if (deref.parent) |parent| { |
| 38322 | return DerefResult{ .val = (try sema.bitCastVal(block, src, parent.tv.val, parent.tv.ty, load_ty, parent.byte_offset)) orelse return .runtime_load }; | 38134 | const parent_ip_index = try parent.val.intern(mod, sema.arena); |
| 38135 | const parent_val = Value.fromInterned(parent_ip_index); | ||
| 38136 | const parent_ty = Type.fromInterned(mod.intern_pool.typeOf(parent_ip_index)); | ||
| 38137 | if (load_sz + parent.byte_offset <= try sema.typeAbiSize(parent_ty)) { | ||
| 38138 | return .{ .val = (try sema.bitCastVal(block, src, parent_val, parent_ty, load_ty, parent.byte_offset)) orelse return .runtime_load }; | ||
| 38139 | } | ||
| 38140 | } | ||
| 38323 | 38141 | ||
| 38324 | if (deref.ty_without_well_defined_layout) |bad_ty| { | 38142 | if (deref.ty_without_well_defined_layout) |bad_ty| { |
| 38325 | // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem | 38143 | // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem |
| 38326 | // is that some type we encountered when de-referencing does not have a well-defined layout. | 38144 | // is that some type we encountered when de-referencing does not have a well-defined layout. |
| 38327 | return DerefResult{ .needed_well_defined = bad_ty }; | 38145 | return .{ .needed_well_defined = bad_ty }; |
| 38328 | } else { | 38146 | } else { |
| 38329 | // If all encountered types had well-defined layouts, the parent is the root decl and it just | 38147 | // If all encountered types had well-defined layouts, the parent is the root decl and it just |
| 38330 | // wasn't big enough for the load. | 38148 | // wasn't big enough for the load. |
| 38331 | return DerefResult{ .out_of_bounds = deref.parent.?.tv.ty }; | 38149 | const parent_ip_index = try deref.parent.?.val.intern(mod, sema.arena); |
| 38150 | const parent_ty = Type.fromInterned(mod.intern_pool.typeOf(parent_ip_index)); | ||
| 38151 | return .{ .out_of_bounds = parent_ty }; | ||
| 38332 | } | 38152 | } |
| 38333 | } | 38153 | } |
| 38334 | 38154 | ||
| ... | @@ -38530,7 +38350,7 @@ fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi | ... | @@ -38530,7 +38350,7 @@ fn intAddInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi |
| 38530 | }, | 38350 | }, |
| 38531 | else => |e| return e, | 38351 | else => |e| return e, |
| 38532 | }; | 38352 | }; |
| 38533 | scalar.* = try val.intern(scalar_ty, mod); | 38353 | scalar.* = val.toIntern(); |
| 38534 | } | 38354 | } |
| 38535 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 38355 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 38536 | .ty = ty.toIntern(), | 38356 | .ty = ty.toIntern(), |
| ... | @@ -38620,7 +38440,7 @@ fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi | ... | @@ -38620,7 +38440,7 @@ fn intSubInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *usi |
| 38620 | }, | 38440 | }, |
| 38621 | else => |e| return e, | 38441 | else => |e| return e, |
| 38622 | }; | 38442 | }; |
| 38623 | scalar.* = try val.intern(scalar_ty, mod); | 38443 | scalar.* = val.toIntern(); |
| 38624 | } | 38444 | } |
| 38625 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 38445 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 38626 | .ty = ty.toIntern(), | 38446 | .ty = ty.toIntern(), |
| ... | @@ -38690,8 +38510,8 @@ fn intSubWithOverflow( | ... | @@ -38690,8 +38510,8 @@ fn intSubWithOverflow( |
| 38690 | const lhs_elem = try lhs.elemValue(sema.mod, i); | 38510 | const lhs_elem = try lhs.elemValue(sema.mod, i); |
| 38691 | const rhs_elem = try rhs.elemValue(sema.mod, i); | 38511 | const rhs_elem = try rhs.elemValue(sema.mod, i); |
| 38692 | const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty); | 38512 | const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty); |
| 38693 | of.* = try of_math_result.overflow_bit.intern(Type.u1, mod); | 38513 | of.* = of_math_result.overflow_bit.toIntern(); |
| 38694 | scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod); | 38514 | scalar.* = of_math_result.wrapped_result.toIntern(); |
| 38695 | } | 38515 | } |
| 38696 | return Value.OverflowArithmeticResult{ | 38516 | return Value.OverflowArithmeticResult{ |
| 38697 | .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 38517 | .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| ... | @@ -38746,19 +38566,17 @@ fn intFromFloat( | ... | @@ -38746,19 +38566,17 @@ fn intFromFloat( |
| 38746 | ) CompileError!Value { | 38566 | ) CompileError!Value { |
| 38747 | const mod = sema.mod; | 38567 | const mod = sema.mod; |
| 38748 | if (float_ty.zigTypeTag(mod) == .Vector) { | 38568 | if (float_ty.zigTypeTag(mod) == .Vector) { |
| 38749 | const elem_ty = float_ty.scalarType(mod); | ||
| 38750 | const result_data = try sema.arena.alloc(InternPool.Index, float_ty.vectorLen(mod)); | 38569 | const result_data = try sema.arena.alloc(InternPool.Index, float_ty.vectorLen(mod)); |
| 38751 | const scalar_ty = int_ty.scalarType(mod); | ||
| 38752 | for (result_data, 0..) |*scalar, i| { | 38570 | for (result_data, 0..) |*scalar, i| { |
| 38753 | const elem_val = try val.elemValue(sema.mod, i); | 38571 | const elem_val = try val.elemValue(sema.mod, i); |
| 38754 | scalar.* = try (try sema.intFromFloatScalar(block, src, elem_val, elem_ty, int_ty.scalarType(mod), mode)).intern(scalar_ty, mod); | 38572 | scalar.* = (try sema.intFromFloatScalar(block, src, elem_val, int_ty.scalarType(mod), mode)).toIntern(); |
| 38755 | } | 38573 | } |
| 38756 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 38574 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 38757 | .ty = int_ty.toIntern(), | 38575 | .ty = int_ty.toIntern(), |
| 38758 | .storage = .{ .elems = result_data }, | 38576 | .storage = .{ .elems = result_data }, |
| 38759 | } }))); | 38577 | } }))); |
| 38760 | } | 38578 | } |
| 38761 | return sema.intFromFloatScalar(block, src, val, float_ty, int_ty, mode); | 38579 | return sema.intFromFloatScalar(block, src, val, int_ty, mode); |
| 38762 | } | 38580 | } |
| 38763 | 38581 | ||
| 38764 | // float is expected to be finite and non-NaN | 38582 | // float is expected to be finite and non-NaN |
| ... | @@ -38791,7 +38609,6 @@ fn intFromFloatScalar( | ... | @@ -38791,7 +38609,6 @@ fn intFromFloatScalar( |
| 38791 | block: *Block, | 38609 | block: *Block, |
| 38792 | src: LazySrcLoc, | 38610 | src: LazySrcLoc, |
| 38793 | val: Value, | 38611 | val: Value, |
| 38794 | float_ty: Type, | ||
| 38795 | int_ty: Type, | 38612 | int_ty: Type, |
| 38796 | mode: IntFromFloatMode, | 38613 | mode: IntFromFloatMode, |
| 38797 | ) CompileError!Value { | 38614 | ) CompileError!Value { |
| ... | @@ -38803,7 +38620,7 @@ fn intFromFloatScalar( | ... | @@ -38803,7 +38620,7 @@ fn intFromFloatScalar( |
| 38803 | block, | 38620 | block, |
| 38804 | src, | 38621 | src, |
| 38805 | "fractional component prevents float value '{}' from coercion to type '{}'", | 38622 | "fractional component prevents float value '{}' from coercion to type '{}'", |
| 38806 | .{ val.fmtValue(float_ty, mod), int_ty.fmt(mod) }, | 38623 | .{ val.fmtValue(mod), int_ty.fmt(mod) }, |
| 38807 | ); | 38624 | ); |
| 38808 | 38625 | ||
| 38809 | const float = val.toFloat(f128, mod); | 38626 | const float = val.toFloat(f128, mod); |
| ... | @@ -38825,7 +38642,7 @@ fn intFromFloatScalar( | ... | @@ -38825,7 +38642,7 @@ fn intFromFloatScalar( |
| 38825 | 38642 | ||
| 38826 | if (!(try sema.intFitsInType(cti_result, int_ty, null))) { | 38643 | if (!(try sema.intFitsInType(cti_result, int_ty, null))) { |
| 38827 | return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{ | 38644 | return sema.fail(block, src, "float value '{}' cannot be stored in integer type '{}'", .{ |
| 38828 | val.fmtValue(float_ty, sema.mod), int_ty.fmt(sema.mod), | 38645 | val.fmtValue(sema.mod), int_ty.fmt(sema.mod), |
| 38829 | }); | 38646 | }); |
| 38830 | } | 38647 | } |
| 38831 | return mod.getCoerced(cti_result, int_ty); | 38648 | return mod.getCoerced(cti_result, int_ty); |
| ... | @@ -38944,8 +38761,8 @@ fn intAddWithOverflow( | ... | @@ -38944,8 +38761,8 @@ fn intAddWithOverflow( |
| 38944 | const lhs_elem = try lhs.elemValue(sema.mod, i); | 38761 | const lhs_elem = try lhs.elemValue(sema.mod, i); |
| 38945 | const rhs_elem = try rhs.elemValue(sema.mod, i); | 38762 | const rhs_elem = try rhs.elemValue(sema.mod, i); |
| 38946 | const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty); | 38763 | const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty); |
| 38947 | of.* = try of_math_result.overflow_bit.intern(Type.u1, mod); | 38764 | of.* = of_math_result.overflow_bit.toIntern(); |
| 38948 | scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod); | 38765 | scalar.* = of_math_result.wrapped_result.toIntern(); |
| 38949 | } | 38766 | } |
| 38950 | return Value.OverflowArithmeticResult{ | 38767 | return Value.OverflowArithmeticResult{ |
| 38951 | .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 38768 | .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| ... | @@ -39055,7 +38872,7 @@ fn compareVector( | ... | @@ -39055,7 +38872,7 @@ fn compareVector( |
| 39055 | const lhs_elem = try lhs.elemValue(sema.mod, i); | 38872 | const lhs_elem = try lhs.elemValue(sema.mod, i); |
| 39056 | const rhs_elem = try rhs.elemValue(sema.mod, i); | 38873 | const rhs_elem = try rhs.elemValue(sema.mod, i); |
| 39057 | const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod)); | 38874 | const res_bool = try sema.compareScalar(lhs_elem, op, rhs_elem, ty.scalarType(mod)); |
| 39058 | scalar.* = try Value.makeBool(res_bool).intern(Type.bool, mod); | 38875 | scalar.* = Value.makeBool(res_bool).toIntern(); |
| 39059 | } | 38876 | } |
| 39060 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 38877 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 39061 | .ty = (try mod.vectorType(.{ .len = ty.vectorLen(mod), .child = .bool_type })).toIntern(), | 38878 | .ty = (try mod.vectorType(.{ .len = ty.vectorLen(mod), .child = .bool_type })).toIntern(), |
| ... | @@ -39232,45 +39049,22 @@ fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Ai | ... | @@ -39232,45 +39049,22 @@ fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Ai |
| 39232 | } | 39049 | } |
| 39233 | 39050 | ||
| 39234 | /// Returns true if any value contained in `val` is undefined. | 39051 | /// Returns true if any value contained in `val` is undefined. |
| 39235 | fn anyUndef(sema: *Sema, val: Value) !bool { | 39052 | fn anyUndef(sema: *Sema, block: *Block, src: LazySrcLoc, val: Value) !bool { |
| 39236 | const mod = sema.mod; | 39053 | const mod = sema.mod; |
| 39237 | if (val.ip_index == .none) return switch (val.tag()) { | 39054 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 39238 | .eu_payload => try sema.anyUndef(val.castTag(.eu_payload).?.data), | 39055 | .undef => true, |
| 39239 | .opt_payload => try sema.anyUndef(val.castTag(.opt_payload).?.data), | 39056 | .simple_value => |v| v == .undefined, |
| 39240 | .repeated => try sema.anyUndef(val.castTag(.repeated).?.data), | ||
| 39241 | .slice => { | 39057 | .slice => { |
| 39242 | const slice = val.castTag(.slice).?.data; | 39058 | // If the slice contents are runtime-known, reification will fail later on with a |
| 39243 | for (0..@intCast(slice.len.toUnsignedInt(mod))) |idx| { | 39059 | // specific error message. |
| 39244 | if (try sema.anyUndef((try slice.ptr.maybeElemValueFull(sema, mod, idx)).?)) return true; | 39060 | const arr = try sema.maybeDerefSliceAsArray(block, src, val) orelse return false; |
| 39245 | } | 39061 | return sema.anyUndef(block, src, arr); |
| 39246 | return false; | 39062 | }, |
| 39247 | }, | 39063 | .aggregate => |aggregate| for (0..aggregate.storage.values().len) |i| { |
| 39248 | .bytes => false, | 39064 | const elem = mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.values()[i]; |
| 39249 | .aggregate => for (val.castTag(.aggregate).?.data) |elem| { | 39065 | if (try sema.anyUndef(block, src, Value.fromInterned(elem))) break true; |
| 39250 | if (try sema.anyUndef(elem)) break true; | ||
| 39251 | } else false, | 39066 | } else false, |
| 39252 | .@"union" => { | 39067 | else => false, |
| 39253 | const un = val.castTag(.@"union").?.data; | ||
| 39254 | if (un.tag) |t| { | ||
| 39255 | if (try sema.anyUndef(t)) return true; | ||
| 39256 | } | ||
| 39257 | return sema.anyUndef(un.val); | ||
| 39258 | }, | ||
| 39259 | }; | ||
| 39260 | return switch (val.toIntern()) { | ||
| 39261 | .undef => true, | ||
| 39262 | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { | ||
| 39263 | .undef => true, | ||
| 39264 | .simple_value => |v| v == .undefined, | ||
| 39265 | .slice => |slice| for (0..@intCast(Value.fromInterned(slice.len).toUnsignedInt(mod))) |idx| { | ||
| 39266 | if (try sema.anyUndef((try val.maybeElemValueFull(sema, mod, idx)).?)) break true; | ||
| 39267 | } else false, | ||
| 39268 | .aggregate => |aggregate| for (0..aggregate.storage.values().len) |i| { | ||
| 39269 | const elem = mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.values()[i]; | ||
| 39270 | if (try sema.anyUndef(Value.fromInterned(elem))) break true; | ||
| 39271 | } else false, | ||
| 39272 | else => false, | ||
| 39273 | }, | ||
| 39274 | }; | 39068 | }; |
| 39275 | } | 39069 | } |
| 39276 | 39070 | ||
| ... | @@ -39283,12 +39077,11 @@ fn sliceToIpString( | ... | @@ -39283,12 +39077,11 @@ fn sliceToIpString( |
| 39283 | reason: NeededComptimeReason, | 39077 | reason: NeededComptimeReason, |
| 39284 | ) CompileError!InternPool.NullTerminatedString { | 39078 | ) CompileError!InternPool.NullTerminatedString { |
| 39285 | const zcu = sema.mod; | 39079 | const zcu = sema.mod; |
| 39286 | const ip = &zcu.intern_pool; | 39080 | const slice_ty = slice_val.typeOf(zcu); |
| 39287 | const slice_ty = Type.fromInterned(ip.typeOf(slice_val.toIntern())); | ||
| 39288 | assert(slice_ty.isSlice(zcu)); | 39081 | assert(slice_ty.isSlice(zcu)); |
| 39289 | assert(slice_ty.childType(zcu).toIntern() == .u8_type); | 39082 | assert(slice_ty.childType(zcu).toIntern() == .u8_type); |
| 39290 | const array_val = try sema.derefSliceAsArray(block, src, slice_val, reason); | 39083 | const array_val = try sema.derefSliceAsArray(block, src, slice_val, reason); |
| 39291 | const array_ty = Type.fromInterned(ip.typeOf(array_val.toIntern())); | 39084 | const array_ty = array_val.typeOf(zcu); |
| 39292 | return array_val.toIpString(array_ty, zcu); | 39085 | return array_val.toIpString(array_ty, zcu); |
| 39293 | } | 39086 | } |
| 39294 | 39087 | ||
| ... | @@ -39302,9 +39095,23 @@ fn derefSliceAsArray( | ... | @@ -39302,9 +39095,23 @@ fn derefSliceAsArray( |
| 39302 | slice_val: Value, | 39095 | slice_val: Value, |
| 39303 | reason: NeededComptimeReason, | 39096 | reason: NeededComptimeReason, |
| 39304 | ) CompileError!Value { | 39097 | ) CompileError!Value { |
| 39098 | return try sema.maybeDerefSliceAsArray(block, src, slice_val) orelse { | ||
| 39099 | return sema.failWithNeededComptime(block, src, reason); | ||
| 39100 | }; | ||
| 39101 | } | ||
| 39102 | |||
| 39103 | /// Given a slice value, attempts to dereference it into a comptime-known array. | ||
| 39104 | /// Returns `null` if the contents of the slice are not comptime-known. | ||
| 39105 | /// Asserts that `slice_val` is a slice. | ||
| 39106 | fn maybeDerefSliceAsArray( | ||
| 39107 | sema: *Sema, | ||
| 39108 | block: *Block, | ||
| 39109 | src: LazySrcLoc, | ||
| 39110 | slice_val: Value, | ||
| 39111 | ) CompileError!?Value { | ||
| 39305 | const zcu = sema.mod; | 39112 | const zcu = sema.mod; |
| 39306 | const ip = &zcu.intern_pool; | 39113 | const ip = &zcu.intern_pool; |
| 39307 | assert(Type.fromInterned(ip.typeOf(slice_val.toIntern())).isSlice(zcu)); | 39114 | assert(slice_val.typeOf(zcu).isSlice(zcu)); |
| 39308 | const slice = switch (ip.indexToKey(slice_val.toIntern())) { | 39115 | const slice = switch (ip.indexToKey(slice_val.toIntern())) { |
| 39309 | .undef => return sema.failWithUseOfUndef(block, src), | 39116 | .undef => return sema.failWithUseOfUndef(block, src), |
| 39310 | .slice => |slice| slice, | 39117 | .slice => |slice| slice, |
| ... | @@ -39324,7 +39131,5 @@ fn derefSliceAsArray( | ... | @@ -39324,7 +39131,5 @@ fn derefSliceAsArray( |
| 39324 | break :p p; | 39131 | break :p p; |
| 39325 | }); | 39132 | }); |
| 39326 | const casted_ptr = try zcu.getCoerced(Value.fromInterned(slice.ptr), ptr_ty); | 39133 | const casted_ptr = try zcu.getCoerced(Value.fromInterned(slice.ptr), ptr_ty); |
| 39327 | return try sema.pointerDeref(block, src, casted_ptr, ptr_ty) orelse { | 39134 | return sema.pointerDeref(block, src, casted_ptr, ptr_ty); |
| 39328 | return sema.failWithNeededComptime(block, src, reason); | ||
| 39329 | }; | ||
| 39330 | } | 39135 | } |
src/TypedValue.zig deleted-528| ... | @@ -1,528 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const Type = @import("type.zig").Type; | ||
| 3 | const Value = @import("Value.zig"); | ||
| 4 | const Module = @import("Module.zig"); | ||
| 5 | const Allocator = std.mem.Allocator; | ||
| 6 | const TypedValue = @This(); | ||
| 7 | const Target = std.Target; | ||
| 8 | |||
| 9 | ty: Type, | ||
| 10 | val: Value, | ||
| 11 | |||
| 12 | /// Memory management for TypedValue. The main purpose of this type | ||
| 13 | /// is to be small and have a deinit() function to free associated resources. | ||
| 14 | pub const Managed = struct { | ||
| 15 | /// If the tag value is less than Tag.no_payload_count, then no pointer | ||
| 16 | /// dereference is needed. | ||
| 17 | typed_value: TypedValue, | ||
| 18 | /// If this is `null` then there is no memory management needed. | ||
| 19 | arena: ?*std.heap.ArenaAllocator.State = null, | ||
| 20 | |||
| 21 | pub fn deinit(self: *Managed, allocator: Allocator) void { | ||
| 22 | if (self.arena) |a| a.promote(allocator).deinit(); | ||
| 23 | self.* = undefined; | ||
| 24 | } | ||
| 25 | }; | ||
| 26 | |||
| 27 | /// Assumes arena allocation. Does a recursive copy. | ||
| 28 | pub fn copy(self: TypedValue, arena: Allocator) error{OutOfMemory}!TypedValue { | ||
| 29 | return TypedValue{ | ||
| 30 | .ty = self.ty, | ||
| 31 | .val = try self.val.copy(arena), | ||
| 32 | }; | ||
| 33 | } | ||
| 34 | |||
| 35 | pub fn eql(a: TypedValue, b: TypedValue, mod: *Module) bool { | ||
| 36 | if (a.ty.toIntern() != b.ty.toIntern()) return false; | ||
| 37 | return a.val.eql(b.val, a.ty, mod); | ||
| 38 | } | ||
| 39 | |||
| 40 | pub fn hash(tv: TypedValue, hasher: *std.hash.Wyhash, mod: *Module) void { | ||
| 41 | return tv.val.hash(tv.ty, hasher, mod); | ||
| 42 | } | ||
| 43 | |||
| 44 | pub fn intFromEnum(tv: TypedValue, mod: *Module) Allocator.Error!Value { | ||
| 45 | return tv.val.intFromEnum(tv.ty, mod); | ||
| 46 | } | ||
| 47 | |||
| 48 | const max_aggregate_items = 100; | ||
| 49 | const max_string_len = 256; | ||
| 50 | |||
| 51 | const FormatContext = struct { | ||
| 52 | tv: TypedValue, | ||
| 53 | mod: *Module, | ||
| 54 | }; | ||
| 55 | |||
| 56 | pub fn format( | ||
| 57 | ctx: FormatContext, | ||
| 58 | comptime fmt: []const u8, | ||
| 59 | options: std.fmt.FormatOptions, | ||
| 60 | writer: anytype, | ||
| 61 | ) !void { | ||
| 62 | _ = options; | ||
| 63 | comptime std.debug.assert(fmt.len == 0); | ||
| 64 | return ctx.tv.print(writer, 3, ctx.mod) catch |err| switch (err) { | ||
| 65 | error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function | ||
| 66 | else => |e| return e, | ||
| 67 | }; | ||
| 68 | } | ||
| 69 | |||
| 70 | /// Prints the Value according to the Type, not according to the Value Tag. | ||
| 71 | pub fn print( | ||
| 72 | tv: TypedValue, | ||
| 73 | writer: anytype, | ||
| 74 | level: u8, | ||
| 75 | mod: *Module, | ||
| 76 | ) (@TypeOf(writer).Error || Allocator.Error)!void { | ||
| 77 | var val = tv.val; | ||
| 78 | var ty = tv.ty; | ||
| 79 | const ip = &mod.intern_pool; | ||
| 80 | while (true) switch (val.ip_index) { | ||
| 81 | .none => switch (val.tag()) { | ||
| 82 | .aggregate => return printAggregate(ty, val, writer, level, mod), | ||
| 83 | .@"union" => { | ||
| 84 | if (level == 0) { | ||
| 85 | return writer.writeAll(".{ ... }"); | ||
| 86 | } | ||
| 87 | const payload = val.castTag(.@"union").?.data; | ||
| 88 | try writer.writeAll(".{ "); | ||
| 89 | |||
| 90 | if (payload.tag) |tag| { | ||
| 91 | try print(.{ | ||
| 92 | .ty = Type.fromInterned(ip.loadUnionType(ty.toIntern()).enum_tag_ty), | ||
| 93 | .val = tag, | ||
| 94 | }, writer, level - 1, mod); | ||
| 95 | try writer.writeAll(" = "); | ||
| 96 | const field_ty = ty.unionFieldType(tag, mod).?; | ||
| 97 | try print(.{ | ||
| 98 | .ty = field_ty, | ||
| 99 | .val = payload.val, | ||
| 100 | }, writer, level - 1, mod); | ||
| 101 | } else { | ||
| 102 | try writer.writeAll("(unknown tag) = "); | ||
| 103 | const backing_ty = try ty.unionBackingType(mod); | ||
| 104 | try print(.{ | ||
| 105 | .ty = backing_ty, | ||
| 106 | .val = payload.val, | ||
| 107 | }, writer, level - 1, mod); | ||
| 108 | } | ||
| 109 | |||
| 110 | return writer.writeAll(" }"); | ||
| 111 | }, | ||
| 112 | .bytes => return writer.print("\"{}\"", .{std.zig.fmtEscapes(val.castTag(.bytes).?.data)}), | ||
| 113 | .repeated => { | ||
| 114 | if (level == 0) { | ||
| 115 | return writer.writeAll(".{ ... }"); | ||
| 116 | } | ||
| 117 | var i: u32 = 0; | ||
| 118 | try writer.writeAll(".{ "); | ||
| 119 | const elem_tv = TypedValue{ | ||
| 120 | .ty = ty.elemType2(mod), | ||
| 121 | .val = val.castTag(.repeated).?.data, | ||
| 122 | }; | ||
| 123 | const len = ty.arrayLen(mod); | ||
| 124 | const max_len = @min(len, max_aggregate_items); | ||
| 125 | while (i < max_len) : (i += 1) { | ||
| 126 | if (i != 0) try writer.writeAll(", "); | ||
| 127 | try print(elem_tv, writer, level - 1, mod); | ||
| 128 | } | ||
| 129 | if (len > max_aggregate_items) { | ||
| 130 | try writer.writeAll(", ..."); | ||
| 131 | } | ||
| 132 | return writer.writeAll(" }"); | ||
| 133 | }, | ||
| 134 | .slice => { | ||
| 135 | if (level == 0) { | ||
| 136 | return writer.writeAll(".{ ... }"); | ||
| 137 | } | ||
| 138 | const payload = val.castTag(.slice).?.data; | ||
| 139 | const elem_ty = ty.elemType2(mod); | ||
| 140 | const len = payload.len.toUnsignedInt(mod); | ||
| 141 | |||
| 142 | if (elem_ty.eql(Type.u8, mod)) str: { | ||
| 143 | const max_len: usize = @min(len, max_string_len); | ||
| 144 | var buf: [max_string_len]u8 = undefined; | ||
| 145 | |||
| 146 | var i: u32 = 0; | ||
| 147 | while (i < max_len) : (i += 1) { | ||
| 148 | const maybe_elem_val = payload.ptr.maybeElemValue(mod, i) catch |err| switch (err) { | ||
| 149 | error.OutOfMemory => @panic("OOM"), // TODO: eliminate this panic | ||
| 150 | }; | ||
| 151 | const elem_val = maybe_elem_val orelse return writer.writeAll(".{ (reinterpreted data) }"); | ||
| 152 | if (elem_val.isUndef(mod)) break :str; | ||
| 153 | buf[i] = std.math.cast(u8, elem_val.toUnsignedInt(mod)) orelse break :str; | ||
| 154 | } | ||
| 155 | |||
| 156 | // TODO would be nice if this had a bit of unicode awareness. | ||
| 157 | const truncated = if (len > max_string_len) " (truncated)" else ""; | ||
| 158 | return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated }); | ||
| 159 | } | ||
| 160 | |||
| 161 | try writer.writeAll(".{ "); | ||
| 162 | |||
| 163 | const max_len = @min(len, max_aggregate_items); | ||
| 164 | var i: u32 = 0; | ||
| 165 | while (i < max_len) : (i += 1) { | ||
| 166 | if (i != 0) try writer.writeAll(", "); | ||
| 167 | const maybe_elem_val = payload.ptr.maybeElemValue(mod, i) catch |err| switch (err) { | ||
| 168 | error.OutOfMemory => @panic("OOM"), // TODO: eliminate this panic | ||
| 169 | }; | ||
| 170 | const elem_val = maybe_elem_val orelse return writer.writeAll("(reinterpreted data) }"); | ||
| 171 | try print(.{ | ||
| 172 | .ty = elem_ty, | ||
| 173 | .val = elem_val, | ||
| 174 | }, writer, level - 1, mod); | ||
| 175 | } | ||
| 176 | if (len > max_aggregate_items) { | ||
| 177 | try writer.writeAll(", ..."); | ||
| 178 | } | ||
| 179 | return writer.writeAll(" }"); | ||
| 180 | }, | ||
| 181 | .eu_payload => { | ||
| 182 | val = val.castTag(.eu_payload).?.data; | ||
| 183 | ty = ty.errorUnionPayload(mod); | ||
| 184 | }, | ||
| 185 | .opt_payload => { | ||
| 186 | val = val.castTag(.opt_payload).?.data; | ||
| 187 | ty = ty.optionalChild(mod); | ||
| 188 | }, | ||
| 189 | }, | ||
| 190 | else => switch (ip.indexToKey(val.toIntern())) { | ||
| 191 | .int_type, | ||
| 192 | .ptr_type, | ||
| 193 | .array_type, | ||
| 194 | .vector_type, | ||
| 195 | .opt_type, | ||
| 196 | .anyframe_type, | ||
| 197 | .error_union_type, | ||
| 198 | .simple_type, | ||
| 199 | .struct_type, | ||
| 200 | .anon_struct_type, | ||
| 201 | .union_type, | ||
| 202 | .opaque_type, | ||
| 203 | .enum_type, | ||
| 204 | .func_type, | ||
| 205 | .error_set_type, | ||
| 206 | .inferred_error_set_type, | ||
| 207 | => return Type.print(val.toType(), writer, mod), | ||
| 208 | .undef => return writer.writeAll("undefined"), | ||
| 209 | .simple_value => |simple_value| switch (simple_value) { | ||
| 210 | .void => return writer.writeAll("{}"), | ||
| 211 | .empty_struct => return printAggregate(ty, val, writer, level, mod), | ||
| 212 | .generic_poison => return writer.writeAll("(generic poison)"), | ||
| 213 | else => return writer.writeAll(@tagName(simple_value)), | ||
| 214 | }, | ||
| 215 | .variable => return writer.writeAll("(variable)"), | ||
| 216 | .extern_func => |extern_func| return writer.print("(extern function '{}')", .{ | ||
| 217 | mod.declPtr(extern_func.decl).name.fmt(ip), | ||
| 218 | }), | ||
| 219 | .func => |func| return writer.print("(function '{}')", .{ | ||
| 220 | mod.declPtr(func.owner_decl).name.fmt(ip), | ||
| 221 | }), | ||
| 222 | .int => |int| switch (int.storage) { | ||
| 223 | inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}), | ||
| 224 | .lazy_align => |lazy_ty| return writer.print("{d}", .{ | ||
| 225 | Type.fromInterned(lazy_ty).abiAlignment(mod), | ||
| 226 | }), | ||
| 227 | .lazy_size => |lazy_ty| return writer.print("{d}", .{ | ||
| 228 | Type.fromInterned(lazy_ty).abiSize(mod), | ||
| 229 | }), | ||
| 230 | }, | ||
| 231 | .err => |err| return writer.print("error.{}", .{ | ||
| 232 | err.name.fmt(ip), | ||
| 233 | }), | ||
| 234 | .error_union => |error_union| switch (error_union.val) { | ||
| 235 | .err_name => |err_name| return writer.print("error.{}", .{ | ||
| 236 | err_name.fmt(ip), | ||
| 237 | }), | ||
| 238 | .payload => |payload| { | ||
| 239 | val = Value.fromInterned(payload); | ||
| 240 | ty = ty.errorUnionPayload(mod); | ||
| 241 | }, | ||
| 242 | }, | ||
| 243 | .enum_literal => |enum_literal| return writer.print(".{}", .{ | ||
| 244 | enum_literal.fmt(ip), | ||
| 245 | }), | ||
| 246 | .enum_tag => |enum_tag| { | ||
| 247 | if (level == 0) { | ||
| 248 | return writer.writeAll("(enum)"); | ||
| 249 | } | ||
| 250 | const enum_type = ip.loadEnumType(ty.toIntern()); | ||
| 251 | if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| { | ||
| 252 | try writer.print(".{i}", .{enum_type.names.get(ip)[tag_index].fmt(ip)}); | ||
| 253 | return; | ||
| 254 | } | ||
| 255 | try writer.writeAll("@enumFromInt("); | ||
| 256 | try print(.{ | ||
| 257 | .ty = Type.fromInterned(ip.typeOf(enum_tag.int)), | ||
| 258 | .val = Value.fromInterned(enum_tag.int), | ||
| 259 | }, writer, level - 1, mod); | ||
| 260 | try writer.writeAll(")"); | ||
| 261 | return; | ||
| 262 | }, | ||
| 263 | .empty_enum_value => return writer.writeAll("(empty enum value)"), | ||
| 264 | .float => |float| switch (float.storage) { | ||
| 265 | inline else => |x| return writer.print("{d}", .{@as(f64, @floatCast(x))}), | ||
| 266 | }, | ||
| 267 | .slice => |slice| { | ||
| 268 | const ptr_ty = switch (ip.indexToKey(slice.ptr)) { | ||
| 269 | .ptr => |ptr| ty: { | ||
| 270 | if (ptr.addr == .int) return print(.{ | ||
| 271 | .ty = Type.fromInterned(ptr.ty), | ||
| 272 | .val = Value.fromInterned(slice.ptr), | ||
| 273 | }, writer, level - 1, mod); | ||
| 274 | break :ty ip.indexToKey(ptr.ty).ptr_type; | ||
| 275 | }, | ||
| 276 | .undef => |ptr_ty| ip.indexToKey(ptr_ty).ptr_type, | ||
| 277 | else => unreachable, | ||
| 278 | }; | ||
| 279 | if (level == 0) { | ||
| 280 | return writer.writeAll(".{ ... }"); | ||
| 281 | } | ||
| 282 | const elem_ty = Type.fromInterned(ptr_ty.child); | ||
| 283 | const len = Value.fromInterned(slice.len).toUnsignedInt(mod); | ||
| 284 | if (elem_ty.eql(Type.u8, mod)) str: { | ||
| 285 | const max_len = @min(len, max_string_len); | ||
| 286 | var buf: [max_string_len]u8 = undefined; | ||
| 287 | for (buf[0..max_len], 0..) |*c, i| { | ||
| 288 | const maybe_elem = try val.maybeElemValue(mod, i); | ||
| 289 | const elem = maybe_elem orelse return writer.writeAll(".{ (reinterpreted data) }"); | ||
| 290 | if (elem.isUndef(mod)) break :str; | ||
| 291 | c.* = @as(u8, @intCast(elem.toUnsignedInt(mod))); | ||
| 292 | } | ||
| 293 | const truncated = if (len > max_string_len) " (truncated)" else ""; | ||
| 294 | return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated }); | ||
| 295 | } | ||
| 296 | try writer.writeAll(".{ "); | ||
| 297 | const max_len = @min(len, max_aggregate_items); | ||
| 298 | for (0..max_len) |i| { | ||
| 299 | if (i != 0) try writer.writeAll(", "); | ||
| 300 | const maybe_elem = try val.maybeElemValue(mod, i); | ||
| 301 | const elem = maybe_elem orelse return writer.writeAll("(reinterpreted data) }"); | ||
| 302 | try print(.{ | ||
| 303 | .ty = elem_ty, | ||
| 304 | .val = elem, | ||
| 305 | }, writer, level - 1, mod); | ||
| 306 | } | ||
| 307 | if (len > max_aggregate_items) { | ||
| 308 | try writer.writeAll(", ..."); | ||
| 309 | } | ||
| 310 | return writer.writeAll(" }"); | ||
| 311 | }, | ||
| 312 | .ptr => |ptr| { | ||
| 313 | switch (ptr.addr) { | ||
| 314 | .decl => |decl_index| { | ||
| 315 | const decl = mod.declPtr(decl_index); | ||
| 316 | if (level == 0) return writer.print("(decl '{}')", .{decl.name.fmt(ip)}); | ||
| 317 | return print(.{ | ||
| 318 | .ty = decl.ty, | ||
| 319 | .val = decl.val, | ||
| 320 | }, writer, level - 1, mod); | ||
| 321 | }, | ||
| 322 | .anon_decl => |anon_decl| { | ||
| 323 | const decl_val = anon_decl.val; | ||
| 324 | if (level == 0) return writer.print("(anon decl '{d}')", .{ | ||
| 325 | @intFromEnum(decl_val), | ||
| 326 | }); | ||
| 327 | return print(.{ | ||
| 328 | .ty = Type.fromInterned(ip.typeOf(decl_val)), | ||
| 329 | .val = Value.fromInterned(decl_val), | ||
| 330 | }, writer, level - 1, mod); | ||
| 331 | }, | ||
| 332 | .comptime_alloc => { | ||
| 333 | // TODO: we need a Sema to print this! | ||
| 334 | return writer.writeAll("(comptime alloc)"); | ||
| 335 | }, | ||
| 336 | .comptime_field => |field_val_ip| { | ||
| 337 | return print(.{ | ||
| 338 | .ty = Type.fromInterned(ip.typeOf(field_val_ip)), | ||
| 339 | .val = Value.fromInterned(field_val_ip), | ||
| 340 | }, writer, level - 1, mod); | ||
| 341 | }, | ||
| 342 | .int => |int_ip| { | ||
| 343 | try writer.writeAll("@ptrFromInt("); | ||
| 344 | try print(.{ | ||
| 345 | .ty = Type.usize, | ||
| 346 | .val = Value.fromInterned(int_ip), | ||
| 347 | }, writer, level - 1, mod); | ||
| 348 | try writer.writeByte(')'); | ||
| 349 | }, | ||
| 350 | .eu_payload => |eu_ip| { | ||
| 351 | try writer.writeAll("(payload of "); | ||
| 352 | try print(.{ | ||
| 353 | .ty = Type.fromInterned(ip.typeOf(eu_ip)), | ||
| 354 | .val = Value.fromInterned(eu_ip), | ||
| 355 | }, writer, level - 1, mod); | ||
| 356 | try writer.writeAll(")"); | ||
| 357 | }, | ||
| 358 | .opt_payload => |opt_ip| { | ||
| 359 | try print(.{ | ||
| 360 | .ty = Type.fromInterned(ip.typeOf(opt_ip)), | ||
| 361 | .val = Value.fromInterned(opt_ip), | ||
| 362 | }, writer, level - 1, mod); | ||
| 363 | try writer.writeAll(".?"); | ||
| 364 | }, | ||
| 365 | .elem => |elem| { | ||
| 366 | if (level == 0) { | ||
| 367 | try writer.writeAll("(...)"); | ||
| 368 | } else { | ||
| 369 | try print(.{ | ||
| 370 | .ty = Type.fromInterned(ip.typeOf(elem.base)), | ||
| 371 | .val = Value.fromInterned(elem.base), | ||
| 372 | }, writer, level - 1, mod); | ||
| 373 | } | ||
| 374 | try writer.print("[{}]", .{elem.index}); | ||
| 375 | }, | ||
| 376 | .field => |field| { | ||
| 377 | const ptr_container_ty = Type.fromInterned(ip.typeOf(field.base)); | ||
| 378 | if (level == 0) { | ||
| 379 | try writer.writeAll("(...)"); | ||
| 380 | } else { | ||
| 381 | try print(.{ | ||
| 382 | .ty = ptr_container_ty, | ||
| 383 | .val = Value.fromInterned(field.base), | ||
| 384 | }, writer, level - 1, mod); | ||
| 385 | } | ||
| 386 | |||
| 387 | const container_ty = ptr_container_ty.childType(mod); | ||
| 388 | switch (container_ty.zigTypeTag(mod)) { | ||
| 389 | .Struct => { | ||
| 390 | if (container_ty.structFieldName(@intCast(field.index), mod).unwrap()) |field_name| { | ||
| 391 | try writer.print(".{i}", .{field_name.fmt(ip)}); | ||
| 392 | } else { | ||
| 393 | try writer.print("[{d}]", .{field.index}); | ||
| 394 | } | ||
| 395 | }, | ||
| 396 | .Union => { | ||
| 397 | const field_name = mod.typeToUnion(container_ty).?.loadTagType(ip).names.get(ip)[@intCast(field.index)]; | ||
| 398 | try writer.print(".{i}", .{field_name.fmt(ip)}); | ||
| 399 | }, | ||
| 400 | .Pointer => { | ||
| 401 | std.debug.assert(container_ty.isSlice(mod)); | ||
| 402 | try writer.writeAll(switch (field.index) { | ||
| 403 | Value.slice_ptr_index => ".ptr", | ||
| 404 | Value.slice_len_index => ".len", | ||
| 405 | else => unreachable, | ||
| 406 | }); | ||
| 407 | }, | ||
| 408 | else => unreachable, | ||
| 409 | } | ||
| 410 | }, | ||
| 411 | } | ||
| 412 | return; | ||
| 413 | }, | ||
| 414 | .opt => |opt| switch (opt.val) { | ||
| 415 | .none => return writer.writeAll("null"), | ||
| 416 | else => |payload| { | ||
| 417 | val = Value.fromInterned(payload); | ||
| 418 | ty = ty.optionalChild(mod); | ||
| 419 | }, | ||
| 420 | }, | ||
| 421 | .aggregate => |aggregate| switch (aggregate.storage) { | ||
| 422 | .bytes => |bytes| { | ||
| 423 | // Strip the 0 sentinel off of strings before printing | ||
| 424 | const zero_sent = blk: { | ||
| 425 | const sent = ty.sentinel(mod) orelse break :blk false; | ||
| 426 | break :blk sent.eql(Value.zero_u8, Type.u8, mod); | ||
| 427 | }; | ||
| 428 | const str = if (zero_sent) bytes[0 .. bytes.len - 1] else bytes; | ||
| 429 | return writer.print("\"{}\"", .{std.zig.fmtEscapes(str)}); | ||
| 430 | }, | ||
| 431 | .elems, .repeated_elem => return printAggregate(ty, val, writer, level, mod), | ||
| 432 | }, | ||
| 433 | .un => |un| { | ||
| 434 | try writer.writeAll(".{ "); | ||
| 435 | if (level > 0) { | ||
| 436 | if (un.tag != .none) { | ||
| 437 | try print(.{ | ||
| 438 | .ty = ty.unionTagTypeHypothetical(mod), | ||
| 439 | .val = Value.fromInterned(un.tag), | ||
| 440 | }, writer, level - 1, mod); | ||
| 441 | try writer.writeAll(" = "); | ||
| 442 | const field_ty = ty.unionFieldType(Value.fromInterned(un.tag), mod).?; | ||
| 443 | try print(.{ | ||
| 444 | .ty = field_ty, | ||
| 445 | .val = Value.fromInterned(un.val), | ||
| 446 | }, writer, level - 1, mod); | ||
| 447 | } else { | ||
| 448 | try writer.writeAll("(unknown tag) = "); | ||
| 449 | const backing_ty = try ty.unionBackingType(mod); | ||
| 450 | try print(.{ | ||
| 451 | .ty = backing_ty, | ||
| 452 | .val = Value.fromInterned(un.val), | ||
| 453 | }, writer, level - 1, mod); | ||
| 454 | } | ||
| 455 | } else try writer.writeAll("..."); | ||
| 456 | return writer.writeAll(" }"); | ||
| 457 | }, | ||
| 458 | .memoized_call => unreachable, | ||
| 459 | }, | ||
| 460 | }; | ||
| 461 | } | ||
| 462 | |||
| 463 | fn printAggregate( | ||
| 464 | ty: Type, | ||
| 465 | val: Value, | ||
| 466 | writer: anytype, | ||
| 467 | level: u8, | ||
| 468 | mod: *Module, | ||
| 469 | ) (@TypeOf(writer).Error || Allocator.Error)!void { | ||
| 470 | if (level == 0) { | ||
| 471 | return writer.writeAll(".{ ... }"); | ||
| 472 | } | ||
| 473 | const ip = &mod.intern_pool; | ||
| 474 | if (ty.zigTypeTag(mod) == .Struct) { | ||
| 475 | try writer.writeAll(".{"); | ||
| 476 | const max_len = @min(ty.structFieldCount(mod), max_aggregate_items); | ||
| 477 | |||
| 478 | for (0..max_len) |i| { | ||
| 479 | if (i != 0) try writer.writeAll(", "); | ||
| 480 | |||
| 481 | const field_name = ty.structFieldName(@intCast(i), mod); | ||
| 482 | |||
| 483 | if (field_name.unwrap()) |name| try writer.print(".{} = ", .{name.fmt(ip)}); | ||
| 484 | try print(.{ | ||
| 485 | .ty = ty.structFieldType(i, mod), | ||
| 486 | .val = try val.fieldValue(mod, i), | ||
| 487 | }, writer, level - 1, mod); | ||
| 488 | } | ||
| 489 | if (ty.structFieldCount(mod) > max_aggregate_items) { | ||
| 490 | try writer.writeAll(", ..."); | ||
| 491 | } | ||
| 492 | return writer.writeAll("}"); | ||
| 493 | } else { | ||
| 494 | const elem_ty = ty.elemType2(mod); | ||
| 495 | const len = ty.arrayLen(mod); | ||
| 496 | |||
| 497 | if (elem_ty.eql(Type.u8, mod)) str: { | ||
| 498 | const max_len: usize = @min(len, max_string_len); | ||
| 499 | var buf: [max_string_len]u8 = undefined; | ||
| 500 | |||
| 501 | var i: u32 = 0; | ||
| 502 | while (i < max_len) : (i += 1) { | ||
| 503 | const elem = try val.fieldValue(mod, i); | ||
| 504 | if (elem.isUndef(mod)) break :str; | ||
| 505 | buf[i] = std.math.cast(u8, elem.toUnsignedInt(mod)) orelse break :str; | ||
| 506 | } | ||
| 507 | |||
| 508 | const truncated = if (len > max_string_len) " (truncated)" else ""; | ||
| 509 | return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated }); | ||
| 510 | } | ||
| 511 | |||
| 512 | try writer.writeAll(".{ "); | ||
| 513 | |||
| 514 | const max_len = @min(len, max_aggregate_items); | ||
| 515 | var i: u32 = 0; | ||
| 516 | while (i < max_len) : (i += 1) { | ||
| 517 | if (i != 0) try writer.writeAll(", "); | ||
| 518 | try print(.{ | ||
| 519 | .ty = elem_ty, | ||
| 520 | .val = try val.fieldValue(mod, i), | ||
| 521 | }, writer, level - 1, mod); | ||
| 522 | } | ||
| 523 | if (len > max_aggregate_items) { | ||
| 524 | try writer.writeAll(", ..."); | ||
| 525 | } | ||
| 526 | return writer.writeAll(" }"); | ||
| 527 | } | ||
| 528 | } | ||
src/Value.zig+174-647| ... | @@ -8,129 +8,13 @@ const Target = std.Target; | ... | @@ -8,129 +8,13 @@ const Target = std.Target; |
| 8 | const Allocator = std.mem.Allocator; | 8 | const Allocator = std.mem.Allocator; |
| 9 | const Zcu = @import("Module.zig"); | 9 | const Zcu = @import("Module.zig"); |
| 10 | const Module = Zcu; | 10 | const Module = Zcu; |
| 11 | const TypedValue = @import("TypedValue.zig"); | ||
| 12 | const Sema = @import("Sema.zig"); | 11 | const Sema = @import("Sema.zig"); |
| 13 | const InternPool = @import("InternPool.zig"); | 12 | const InternPool = @import("InternPool.zig"); |
| 13 | const print_value = @import("print_value.zig"); | ||
| 14 | const Value = @This(); | 14 | const Value = @This(); |
| 15 | 15 | ||
| 16 | /// We are migrating towards using this for every Value object. However, many | ||
| 17 | /// values are still represented the legacy way. This is indicated by using | ||
| 18 | /// InternPool.Index.none. | ||
| 19 | ip_index: InternPool.Index, | 16 | ip_index: InternPool.Index, |
| 20 | 17 | ||
| 21 | /// This is the raw data, with no bookkeeping, no memory awareness, | ||
| 22 | /// no de-duplication, and no type system awareness. | ||
| 23 | /// This union takes advantage of the fact that the first page of memory | ||
| 24 | /// is unmapped, giving us 4096 possible enum tags that have no payload. | ||
| 25 | legacy: extern union { | ||
| 26 | ptr_otherwise: *Payload, | ||
| 27 | }, | ||
| 28 | |||
| 29 | // Keep in sync with tools/stage2_pretty_printers_common.py | ||
| 30 | pub const Tag = enum(usize) { | ||
| 31 | // The first section of this enum are tags that require no payload. | ||
| 32 | // After this, the tag requires a payload. | ||
| 33 | |||
| 34 | /// When the type is error union: | ||
| 35 | /// * If the tag is `.@"error"`, the error union is an error. | ||
| 36 | /// * If the tag is `.eu_payload`, the error union is a payload. | ||
| 37 | /// * A nested error such as `anyerror!(anyerror!T)` in which the the outer error union | ||
| 38 | /// is non-error, but the inner error union is an error, is represented as | ||
| 39 | /// a tag of `.eu_payload`, with a sub-tag of `.@"error"`. | ||
| 40 | eu_payload, | ||
| 41 | /// When the type is optional: | ||
| 42 | /// * If the tag is `.null_value`, the optional is null. | ||
| 43 | /// * If the tag is `.opt_payload`, the optional is a payload. | ||
| 44 | /// * A nested optional such as `??T` in which the the outer optional | ||
| 45 | /// is non-null, but the inner optional is null, is represented as | ||
| 46 | /// a tag of `.opt_payload`, with a sub-tag of `.null_value`. | ||
| 47 | opt_payload, | ||
| 48 | /// Pointer and length as sub `Value` objects. | ||
| 49 | slice, | ||
| 50 | /// A slice of u8 whose memory is managed externally. | ||
| 51 | bytes, | ||
| 52 | /// This value is repeated some number of times. The amount of times to repeat | ||
| 53 | /// is stored externally. | ||
| 54 | repeated, | ||
| 55 | /// An instance of a struct, array, or vector. | ||
| 56 | /// Each element/field stored as a `Value`. | ||
| 57 | /// In the case of sentinel-terminated arrays, the sentinel value *is* stored, | ||
| 58 | /// so the slice length will be one more than the type's array length. | ||
| 59 | aggregate, | ||
| 60 | /// An instance of a union. | ||
| 61 | @"union", | ||
| 62 | |||
| 63 | pub fn Type(comptime t: Tag) type { | ||
| 64 | return switch (t) { | ||
| 65 | .eu_payload, | ||
| 66 | .opt_payload, | ||
| 67 | .repeated, | ||
| 68 | => Payload.SubValue, | ||
| 69 | .slice => Payload.Slice, | ||
| 70 | .bytes => Payload.Bytes, | ||
| 71 | .aggregate => Payload.Aggregate, | ||
| 72 | .@"union" => Payload.Union, | ||
| 73 | }; | ||
| 74 | } | ||
| 75 | |||
| 76 | pub fn create(comptime t: Tag, ally: Allocator, data: Data(t)) error{OutOfMemory}!Value { | ||
| 77 | const ptr = try ally.create(t.Type()); | ||
| 78 | ptr.* = .{ | ||
| 79 | .base = .{ .tag = t }, | ||
| 80 | .data = data, | ||
| 81 | }; | ||
| 82 | return Value{ | ||
| 83 | .ip_index = .none, | ||
| 84 | .legacy = .{ .ptr_otherwise = &ptr.base }, | ||
| 85 | }; | ||
| 86 | } | ||
| 87 | |||
| 88 | pub fn Data(comptime t: Tag) type { | ||
| 89 | return std.meta.fieldInfo(t.Type(), .data).type; | ||
| 90 | } | ||
| 91 | }; | ||
| 92 | |||
| 93 | pub fn initPayload(payload: *Payload) Value { | ||
| 94 | return Value{ | ||
| 95 | .ip_index = .none, | ||
| 96 | .legacy = .{ .ptr_otherwise = payload }, | ||
| 97 | }; | ||
| 98 | } | ||
| 99 | |||
| 100 | pub fn tag(self: Value) Tag { | ||
| 101 | assert(self.ip_index == .none); | ||
| 102 | return self.legacy.ptr_otherwise.tag; | ||
| 103 | } | ||
| 104 | |||
| 105 | /// Prefer `castTag` to this. | ||
| 106 | pub fn cast(self: Value, comptime T: type) ?*T { | ||
| 107 | if (self.ip_index != .none) { | ||
| 108 | return null; | ||
| 109 | } | ||
| 110 | if (@hasField(T, "base_tag")) { | ||
| 111 | return self.castTag(T.base_tag); | ||
| 112 | } | ||
| 113 | inline for (@typeInfo(Tag).Enum.fields) |field| { | ||
| 114 | const t = @as(Tag, @enumFromInt(field.value)); | ||
| 115 | if (self.legacy.ptr_otherwise.tag == t) { | ||
| 116 | if (T == t.Type()) { | ||
| 117 | return @fieldParentPtr(T, "base", self.legacy.ptr_otherwise); | ||
| 118 | } | ||
| 119 | return null; | ||
| 120 | } | ||
| 121 | } | ||
| 122 | unreachable; | ||
| 123 | } | ||
| 124 | |||
| 125 | pub fn castTag(self: Value, comptime t: Tag) ?*t.Type() { | ||
| 126 | if (self.ip_index != .none) return null; | ||
| 127 | |||
| 128 | if (self.legacy.ptr_otherwise.tag == t) | ||
| 129 | return @fieldParentPtr(t.Type(), "base", self.legacy.ptr_otherwise); | ||
| 130 | |||
| 131 | return null; | ||
| 132 | } | ||
| 133 | |||
| 134 | pub fn format(val: Value, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { | 18 | pub fn format(val: Value, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { |
| 135 | _ = val; | 19 | _ = val; |
| 136 | _ = fmt; | 20 | _ = fmt; |
| ... | @@ -148,42 +32,16 @@ pub fn dump( | ... | @@ -148,42 +32,16 @@ pub fn dump( |
| 148 | out_stream: anytype, | 32 | out_stream: anytype, |
| 149 | ) !void { | 33 | ) !void { |
| 150 | comptime assert(fmt.len == 0); | 34 | comptime assert(fmt.len == 0); |
| 151 | if (start_val.ip_index != .none) { | 35 | try out_stream.print("(interned: {})", .{start_val.toIntern()}); |
| 152 | try out_stream.print("(interned: {})", .{start_val.toIntern()}); | ||
| 153 | return; | ||
| 154 | } | ||
| 155 | var val = start_val; | ||
| 156 | while (true) switch (val.tag()) { | ||
| 157 | .aggregate => { | ||
| 158 | return out_stream.writeAll("(aggregate)"); | ||
| 159 | }, | ||
| 160 | .@"union" => { | ||
| 161 | return out_stream.writeAll("(union value)"); | ||
| 162 | }, | ||
| 163 | .bytes => return out_stream.print("\"{}\"", .{std.zig.fmtEscapes(val.castTag(.bytes).?.data)}), | ||
| 164 | .repeated => { | ||
| 165 | try out_stream.writeAll("(repeated) "); | ||
| 166 | val = val.castTag(.repeated).?.data; | ||
| 167 | }, | ||
| 168 | .eu_payload => { | ||
| 169 | try out_stream.writeAll("(eu_payload) "); | ||
| 170 | val = val.castTag(.repeated).?.data; | ||
| 171 | }, | ||
| 172 | .opt_payload => { | ||
| 173 | try out_stream.writeAll("(opt_payload) "); | ||
| 174 | val = val.castTag(.repeated).?.data; | ||
| 175 | }, | ||
| 176 | .slice => return out_stream.writeAll("(slice)"), | ||
| 177 | }; | ||
| 178 | } | 36 | } |
| 179 | 37 | ||
| 180 | pub fn fmtDebug(val: Value) std.fmt.Formatter(dump) { | 38 | pub fn fmtDebug(val: Value) std.fmt.Formatter(dump) { |
| 181 | return .{ .data = val }; | 39 | return .{ .data = val }; |
| 182 | } | 40 | } |
| 183 | 41 | ||
| 184 | pub fn fmtValue(val: Value, ty: Type, mod: *Module) std.fmt.Formatter(TypedValue.format) { | 42 | pub fn fmtValue(val: Value, mod: *Module) std.fmt.Formatter(print_value.format) { |
| 185 | return .{ .data = .{ | 43 | return .{ .data = .{ |
| 186 | .tv = .{ .ty = ty, .val = val }, | 44 | .val = val, |
| 187 | .mod = mod, | 45 | .mod = mod, |
| 188 | } }; | 46 | } }; |
| 189 | } | 47 | } |
| ... | @@ -252,162 +110,9 @@ fn arrayToIpString(val: Value, len_u64: u64, mod: *Module) !InternPool.NullTermi | ... | @@ -252,162 +110,9 @@ fn arrayToIpString(val: Value, len_u64: u64, mod: *Module) !InternPool.NullTermi |
| 252 | return ip.getOrPutTrailingString(gpa, len); | 110 | return ip.getOrPutTrailingString(gpa, len); |
| 253 | } | 111 | } |
| 254 | 112 | ||
| 255 | pub fn intern2(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index { | ||
| 256 | if (val.ip_index != .none) return val.ip_index; | ||
| 257 | return intern(val, ty, mod); | ||
| 258 | } | ||
| 259 | |||
| 260 | pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index { | ||
| 261 | if (val.ip_index != .none) return (try mod.getCoerced(val, ty)).toIntern(); | ||
| 262 | const ip = &mod.intern_pool; | ||
| 263 | switch (val.tag()) { | ||
| 264 | .eu_payload => { | ||
| 265 | const pl = val.castTag(.eu_payload).?.data; | ||
| 266 | return mod.intern(.{ .error_union = .{ | ||
| 267 | .ty = ty.toIntern(), | ||
| 268 | .val = .{ .payload = try pl.intern(ty.errorUnionPayload(mod), mod) }, | ||
| 269 | } }); | ||
| 270 | }, | ||
| 271 | .opt_payload => { | ||
| 272 | const pl = val.castTag(.opt_payload).?.data; | ||
| 273 | return mod.intern(.{ .opt = .{ | ||
| 274 | .ty = ty.toIntern(), | ||
| 275 | .val = try pl.intern(ty.optionalChild(mod), mod), | ||
| 276 | } }); | ||
| 277 | }, | ||
| 278 | .slice => { | ||
| 279 | const pl = val.castTag(.slice).?.data; | ||
| 280 | return mod.intern(.{ .slice = .{ | ||
| 281 | .ty = ty.toIntern(), | ||
| 282 | .len = try pl.len.intern(Type.usize, mod), | ||
| 283 | .ptr = try pl.ptr.intern(ty.slicePtrFieldType(mod), mod), | ||
| 284 | } }); | ||
| 285 | }, | ||
| 286 | .bytes => { | ||
| 287 | const pl = val.castTag(.bytes).?.data; | ||
| 288 | return mod.intern(.{ .aggregate = .{ | ||
| 289 | .ty = ty.toIntern(), | ||
| 290 | .storage = .{ .bytes = pl }, | ||
| 291 | } }); | ||
| 292 | }, | ||
| 293 | .repeated => { | ||
| 294 | const pl = val.castTag(.repeated).?.data; | ||
| 295 | return mod.intern(.{ .aggregate = .{ | ||
| 296 | .ty = ty.toIntern(), | ||
| 297 | .storage = .{ .repeated_elem = try pl.intern(ty.childType(mod), mod) }, | ||
| 298 | } }); | ||
| 299 | }, | ||
| 300 | .aggregate => { | ||
| 301 | const len = @as(usize, @intCast(ty.arrayLen(mod))); | ||
| 302 | const old_elems = val.castTag(.aggregate).?.data[0..len]; | ||
| 303 | const new_elems = try mod.gpa.alloc(InternPool.Index, old_elems.len); | ||
| 304 | defer mod.gpa.free(new_elems); | ||
| 305 | const ty_key = ip.indexToKey(ty.toIntern()); | ||
| 306 | for (new_elems, old_elems, 0..) |*new_elem, old_elem, field_i| | ||
| 307 | new_elem.* = try old_elem.intern(switch (ty_key) { | ||
| 308 | .struct_type => ty.structFieldType(field_i, mod), | ||
| 309 | .anon_struct_type => |info| Type.fromInterned(info.types.get(ip)[field_i]), | ||
| 310 | inline .array_type, .vector_type => |info| Type.fromInterned(info.child), | ||
| 311 | else => unreachable, | ||
| 312 | }, mod); | ||
| 313 | return mod.intern(.{ .aggregate = .{ | ||
| 314 | .ty = ty.toIntern(), | ||
| 315 | .storage = .{ .elems = new_elems }, | ||
| 316 | } }); | ||
| 317 | }, | ||
| 318 | .@"union" => { | ||
| 319 | const pl = val.castTag(.@"union").?.data; | ||
| 320 | if (pl.tag) |pl_tag| { | ||
| 321 | return mod.intern(.{ .un = .{ | ||
| 322 | .ty = ty.toIntern(), | ||
| 323 | .tag = try pl_tag.intern(ty.unionTagTypeHypothetical(mod), mod), | ||
| 324 | .val = try pl.val.intern(ty.unionFieldType(pl_tag, mod).?, mod), | ||
| 325 | } }); | ||
| 326 | } else { | ||
| 327 | return mod.intern(.{ .un = .{ | ||
| 328 | .ty = ty.toIntern(), | ||
| 329 | .tag = .none, | ||
| 330 | .val = try pl.val.intern(try ty.unionBackingType(mod), mod), | ||
| 331 | } }); | ||
| 332 | } | ||
| 333 | }, | ||
| 334 | } | ||
| 335 | } | ||
| 336 | |||
| 337 | pub fn unintern(val: Value, arena: Allocator, mod: *Module) Allocator.Error!Value { | ||
| 338 | return if (val.ip_index == .none) val else switch (mod.intern_pool.indexToKey(val.toIntern())) { | ||
| 339 | .int_type, | ||
| 340 | .ptr_type, | ||
| 341 | .array_type, | ||
| 342 | .vector_type, | ||
| 343 | .opt_type, | ||
| 344 | .anyframe_type, | ||
| 345 | .error_union_type, | ||
| 346 | .simple_type, | ||
| 347 | .struct_type, | ||
| 348 | .anon_struct_type, | ||
| 349 | .union_type, | ||
| 350 | .opaque_type, | ||
| 351 | .enum_type, | ||
| 352 | .func_type, | ||
| 353 | .error_set_type, | ||
| 354 | .inferred_error_set_type, | ||
| 355 | |||
| 356 | .undef, | ||
| 357 | .simple_value, | ||
| 358 | .variable, | ||
| 359 | .extern_func, | ||
| 360 | .func, | ||
| 361 | .int, | ||
| 362 | .err, | ||
| 363 | .enum_literal, | ||
| 364 | .enum_tag, | ||
| 365 | .empty_enum_value, | ||
| 366 | .float, | ||
| 367 | .ptr, | ||
| 368 | => val, | ||
| 369 | |||
| 370 | .error_union => |error_union| switch (error_union.val) { | ||
| 371 | .err_name => val, | ||
| 372 | .payload => |payload| Tag.eu_payload.create(arena, Value.fromInterned(payload)), | ||
| 373 | }, | ||
| 374 | |||
| 375 | .slice => |slice| Tag.slice.create(arena, .{ | ||
| 376 | .ptr = Value.fromInterned(slice.ptr), | ||
| 377 | .len = Value.fromInterned(slice.len), | ||
| 378 | }), | ||
| 379 | |||
| 380 | .opt => |opt| switch (opt.val) { | ||
| 381 | .none => val, | ||
| 382 | else => |payload| Tag.opt_payload.create(arena, Value.fromInterned(payload)), | ||
| 383 | }, | ||
| 384 | |||
| 385 | .aggregate => |aggregate| switch (aggregate.storage) { | ||
| 386 | .bytes => |bytes| Tag.bytes.create(arena, try arena.dupe(u8, bytes)), | ||
| 387 | .elems => |old_elems| { | ||
| 388 | const new_elems = try arena.alloc(Value, old_elems.len); | ||
| 389 | for (new_elems, old_elems) |*new_elem, old_elem| new_elem.* = Value.fromInterned(old_elem); | ||
| 390 | return Tag.aggregate.create(arena, new_elems); | ||
| 391 | }, | ||
| 392 | .repeated_elem => |elem| Tag.repeated.create(arena, Value.fromInterned(elem)), | ||
| 393 | }, | ||
| 394 | |||
| 395 | .un => |un| Tag.@"union".create(arena, .{ | ||
| 396 | // toValue asserts that the value cannot be .none which is valid on unions. | ||
| 397 | .tag = if (un.tag == .none) null else Value.fromInterned(un.tag), | ||
| 398 | .val = Value.fromInterned(un.val), | ||
| 399 | }), | ||
| 400 | |||
| 401 | .memoized_call => unreachable, | ||
| 402 | }; | ||
| 403 | } | ||
| 404 | |||
| 405 | pub fn fromInterned(i: InternPool.Index) Value { | 113 | pub fn fromInterned(i: InternPool.Index) Value { |
| 406 | assert(i != .none); | 114 | assert(i != .none); |
| 407 | return .{ | 115 | return .{ .ip_index = i }; |
| 408 | .ip_index = i, | ||
| 409 | .legacy = undefined, | ||
| 410 | }; | ||
| 411 | } | 116 | } |
| 412 | 117 | ||
| 413 | pub fn toIntern(val: Value) InternPool.Index { | 118 | pub fn toIntern(val: Value) InternPool.Index { |
| ... | @@ -492,24 +197,24 @@ pub fn isFuncBody(val: Value, mod: *Module) bool { | ... | @@ -492,24 +197,24 @@ pub fn isFuncBody(val: Value, mod: *Module) bool { |
| 492 | } | 197 | } |
| 493 | 198 | ||
| 494 | pub fn getFunction(val: Value, mod: *Module) ?InternPool.Key.Func { | 199 | pub fn getFunction(val: Value, mod: *Module) ?InternPool.Key.Func { |
| 495 | return if (val.ip_index != .none) switch (mod.intern_pool.indexToKey(val.toIntern())) { | 200 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 496 | .func => |x| x, | 201 | .func => |x| x, |
| 497 | else => null, | 202 | else => null, |
| 498 | } else null; | 203 | }; |
| 499 | } | 204 | } |
| 500 | 205 | ||
| 501 | pub fn getExternFunc(val: Value, mod: *Module) ?InternPool.Key.ExternFunc { | 206 | pub fn getExternFunc(val: Value, mod: *Module) ?InternPool.Key.ExternFunc { |
| 502 | return if (val.ip_index != .none) switch (mod.intern_pool.indexToKey(val.toIntern())) { | 207 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 503 | .extern_func => |extern_func| extern_func, | 208 | .extern_func => |extern_func| extern_func, |
| 504 | else => null, | 209 | else => null, |
| 505 | } else null; | 210 | }; |
| 506 | } | 211 | } |
| 507 | 212 | ||
| 508 | pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable { | 213 | pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable { |
| 509 | return if (val.ip_index != .none) switch (mod.intern_pool.indexToKey(val.toIntern())) { | 214 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 510 | .variable => |variable| variable, | 215 | .variable => |variable| variable, |
| 511 | else => null, | 216 | else => null, |
| 512 | } else null; | 217 | }; |
| 513 | } | 218 | } |
| 514 | 219 | ||
| 515 | /// If the value fits in a u64, return it, otherwise null. | 220 | /// If the value fits in a u64, return it, otherwise null. |
| ... | @@ -544,12 +249,12 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, opt_sema: ?*Sema) !?u64 | ... | @@ -544,12 +249,12 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, opt_sema: ?*Sema) !?u64 |
| 544 | .int => |int| Value.fromInterned(int).getUnsignedIntAdvanced(mod, opt_sema), | 249 | .int => |int| Value.fromInterned(int).getUnsignedIntAdvanced(mod, opt_sema), |
| 545 | .elem => |elem| { | 250 | .elem => |elem| { |
| 546 | const base_addr = (try Value.fromInterned(elem.base).getUnsignedIntAdvanced(mod, opt_sema)) orelse return null; | 251 | const base_addr = (try Value.fromInterned(elem.base).getUnsignedIntAdvanced(mod, opt_sema)) orelse return null; |
| 547 | const elem_ty = Type.fromInterned(mod.intern_pool.typeOf(elem.base)).elemType2(mod); | 252 | const elem_ty = Value.fromInterned(elem.base).typeOf(mod).elemType2(mod); |
| 548 | return base_addr + elem.index * elem_ty.abiSize(mod); | 253 | return base_addr + elem.index * elem_ty.abiSize(mod); |
| 549 | }, | 254 | }, |
| 550 | .field => |field| { | 255 | .field => |field| { |
| 551 | const base_addr = (try Value.fromInterned(field.base).getUnsignedIntAdvanced(mod, opt_sema)) orelse return null; | 256 | const base_addr = (try Value.fromInterned(field.base).getUnsignedIntAdvanced(mod, opt_sema)) orelse return null; |
| 552 | const struct_ty = Type.fromInterned(mod.intern_pool.typeOf(field.base)).childType(mod); | 257 | const struct_ty = Value.fromInterned(field.base).typeOf(mod).childType(mod); |
| 553 | if (opt_sema) |sema| try sema.resolveTypeLayout(struct_ty); | 258 | if (opt_sema) |sema| try sema.resolveTypeLayout(struct_ty); |
| 554 | return base_addr + struct_ty.structFieldOffset(@as(usize, @intCast(field.index)), mod); | 259 | return base_addr + struct_ty.structFieldOffset(@as(usize, @intCast(field.index)), mod); |
| 555 | }, | 260 | }, |
| ... | @@ -600,16 +305,16 @@ pub fn toBool(val: Value) bool { | ... | @@ -600,16 +305,16 @@ pub fn toBool(val: Value) bool { |
| 600 | }; | 305 | }; |
| 601 | } | 306 | } |
| 602 | 307 | ||
| 603 | fn isDeclRef(val: Value, mod: *Module) bool { | 308 | fn ptrHasIntAddr(val: Value, mod: *Module) bool { |
| 604 | var check = val; | 309 | var check = val; |
| 605 | while (true) switch (mod.intern_pool.indexToKey(check.toIntern())) { | 310 | while (true) switch (mod.intern_pool.indexToKey(check.toIntern())) { |
| 606 | .ptr => |ptr| switch (ptr.addr) { | 311 | .ptr => |ptr| switch (ptr.addr) { |
| 607 | .decl, .comptime_alloc, .comptime_field, .anon_decl => return true, | 312 | .decl, .comptime_alloc, .comptime_field, .anon_decl => return false, |
| 313 | .int => return true, | ||
| 608 | .eu_payload, .opt_payload => |base| check = Value.fromInterned(base), | 314 | .eu_payload, .opt_payload => |base| check = Value.fromInterned(base), |
| 609 | .elem, .field => |base_index| check = Value.fromInterned(base_index.base), | 315 | .elem, .field => |base_index| check = Value.fromInterned(base_index.base), |
| 610 | .int => return false, | ||
| 611 | }, | 316 | }, |
| 612 | else => return false, | 317 | else => unreachable, |
| 613 | }; | 318 | }; |
| 614 | } | 319 | } |
| 615 | 320 | ||
| ... | @@ -677,25 +382,14 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{ | ... | @@ -677,25 +382,14 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{ |
| 677 | .auto => return error.IllDefinedMemoryLayout, | 382 | .auto => return error.IllDefinedMemoryLayout, |
| 678 | .@"extern" => for (0..struct_type.field_types.len) |i| { | 383 | .@"extern" => for (0..struct_type.field_types.len) |i| { |
| 679 | const off: usize = @intCast(ty.structFieldOffset(i, mod)); | 384 | const off: usize = @intCast(ty.structFieldOffset(i, mod)); |
| 680 | const field_val = switch (val.ip_index) { | 385 | const field_val = Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 681 | .none => switch (val.tag()) { | 386 | .bytes => |bytes| { |
| 682 | .bytes => { | 387 | buffer[off] = bytes[i]; |
| 683 | buffer[off] = val.castTag(.bytes).?.data[i]; | 388 | continue; |
| 684 | continue; | ||
| 685 | }, | ||
| 686 | .aggregate => val.castTag(.aggregate).?.data[i], | ||
| 687 | .repeated => val.castTag(.repeated).?.data, | ||
| 688 | else => unreachable, | ||
| 689 | }, | 389 | }, |
| 690 | else => Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) { | 390 | .elems => |elems| elems[i], |
| 691 | .bytes => |bytes| { | 391 | .repeated_elem => |elem| elem, |
| 692 | buffer[off] = bytes[i]; | 392 | }); |
| 693 | continue; | ||
| 694 | }, | ||
| 695 | .elems => |elems| elems[i], | ||
| 696 | .repeated_elem => |elem| elem, | ||
| 697 | }), | ||
| 698 | }; | ||
| 699 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 393 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 700 | try writeToMemory(field_val, field_ty, mod, buffer[off..]); | 394 | try writeToMemory(field_val, field_ty, mod, buffer[off..]); |
| 701 | }, | 395 | }, |
| ... | @@ -745,7 +439,7 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{ | ... | @@ -745,7 +439,7 @@ pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) error{ |
| 745 | }, | 439 | }, |
| 746 | .Pointer => { | 440 | .Pointer => { |
| 747 | if (ty.isSlice(mod)) return error.IllDefinedMemoryLayout; | 441 | if (ty.isSlice(mod)) return error.IllDefinedMemoryLayout; |
| 748 | if (val.isDeclRef(mod)) return error.ReinterpretDeclRef; | 442 | if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef; |
| 749 | return val.writeToMemory(Type.usize, mod, buffer); | 443 | return val.writeToMemory(Type.usize, mod, buffer); |
| 750 | }, | 444 | }, |
| 751 | .Optional => { | 445 | .Optional => { |
| ... | @@ -842,19 +536,11 @@ pub fn writeToPackedMemory( | ... | @@ -842,19 +536,11 @@ pub fn writeToPackedMemory( |
| 842 | assert(struct_type.layout == .@"packed"); | 536 | assert(struct_type.layout == .@"packed"); |
| 843 | var bits: u16 = 0; | 537 | var bits: u16 = 0; |
| 844 | for (0..struct_type.field_types.len) |i| { | 538 | for (0..struct_type.field_types.len) |i| { |
| 845 | const field_val = switch (val.ip_index) { | 539 | const field_val = Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 846 | .none => switch (val.tag()) { | 540 | .bytes => unreachable, |
| 847 | .bytes => unreachable, | 541 | .elems => |elems| elems[i], |
| 848 | .aggregate => val.castTag(.aggregate).?.data[i], | 542 | .repeated_elem => |elem| elem, |
| 849 | .repeated => val.castTag(.repeated).?.data, | 543 | }); |
| 850 | else => unreachable, | ||
| 851 | }, | ||
| 852 | else => Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) { | ||
| 853 | .bytes => unreachable, | ||
| 854 | .elems => |elems| elems[i], | ||
| 855 | .repeated_elem => |elem| elem, | ||
| 856 | }), | ||
| 857 | }; | ||
| 858 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 544 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 859 | const field_bits: u16 = @intCast(field_ty.bitSize(mod)); | 545 | const field_bits: u16 = @intCast(field_ty.bitSize(mod)); |
| 860 | try field_val.writeToPackedMemory(field_ty, mod, buffer, bit_offset + bits); | 546 | try field_val.writeToPackedMemory(field_ty, mod, buffer, bit_offset + bits); |
| ... | @@ -880,7 +566,7 @@ pub fn writeToPackedMemory( | ... | @@ -880,7 +566,7 @@ pub fn writeToPackedMemory( |
| 880 | }, | 566 | }, |
| 881 | .Pointer => { | 567 | .Pointer => { |
| 882 | assert(!ty.isSlice(mod)); // No well defined layout. | 568 | assert(!ty.isSlice(mod)); // No well defined layout. |
| 883 | if (val.isDeclRef(mod)) return error.ReinterpretDeclRef; | 569 | if (!val.ptrHasIntAddr(mod)) return error.ReinterpretDeclRef; |
| 884 | return val.writeToPackedMemory(Type.usize, mod, buffer, bit_offset); | 570 | return val.writeToPackedMemory(Type.usize, mod, buffer, bit_offset); |
| 885 | }, | 571 | }, |
| 886 | .Optional => { | 572 | .Optional => { |
| ... | @@ -972,7 +658,7 @@ pub fn readFromMemory( | ... | @@ -972,7 +658,7 @@ pub fn readFromMemory( |
| 972 | const elems = try arena.alloc(InternPool.Index, @as(usize, @intCast(ty.arrayLen(mod)))); | 658 | const elems = try arena.alloc(InternPool.Index, @as(usize, @intCast(ty.arrayLen(mod)))); |
| 973 | var offset: usize = 0; | 659 | var offset: usize = 0; |
| 974 | for (elems) |*elem| { | 660 | for (elems) |*elem| { |
| 975 | elem.* = try (try readFromMemory(elem_ty, mod, buffer[offset..], arena)).intern(elem_ty, mod); | 661 | elem.* = (try readFromMemory(elem_ty, mod, buffer[offset..], arena)).toIntern(); |
| 976 | offset += @as(usize, @intCast(elem_size)); | 662 | offset += @as(usize, @intCast(elem_size)); |
| 977 | } | 663 | } |
| 978 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 664 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| ... | @@ -997,7 +683,7 @@ pub fn readFromMemory( | ... | @@ -997,7 +683,7 @@ pub fn readFromMemory( |
| 997 | const field_ty = Type.fromInterned(field_types.get(ip)[i]); | 683 | const field_ty = Type.fromInterned(field_types.get(ip)[i]); |
| 998 | const off: usize = @intCast(ty.structFieldOffset(i, mod)); | 684 | const off: usize = @intCast(ty.structFieldOffset(i, mod)); |
| 999 | const sz: usize = @intCast(field_ty.abiSize(mod)); | 685 | const sz: usize = @intCast(field_ty.abiSize(mod)); |
| 1000 | field_val.* = try (try readFromMemory(field_ty, mod, buffer[off..(off + sz)], arena)).intern(field_ty, mod); | 686 | field_val.* = (try readFromMemory(field_ty, mod, buffer[off..(off + sz)], arena)).toIntern(); |
| 1001 | } | 687 | } |
| 1002 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 688 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 1003 | .ty = ty.toIntern(), | 689 | .ty = ty.toIntern(), |
| ... | @@ -1027,7 +713,7 @@ pub fn readFromMemory( | ... | @@ -1027,7 +713,7 @@ pub fn readFromMemory( |
| 1027 | .@"extern" => { | 713 | .@"extern" => { |
| 1028 | const union_size = ty.abiSize(mod); | 714 | const union_size = ty.abiSize(mod); |
| 1029 | const array_ty = try mod.arrayType(.{ .len = union_size, .child = .u8_type }); | 715 | const array_ty = try mod.arrayType(.{ .len = union_size, .child = .u8_type }); |
| 1030 | const val = try (try readFromMemory(array_ty, mod, buffer, arena)).intern(array_ty, mod); | 716 | const val = (try readFromMemory(array_ty, mod, buffer, arena)).toIntern(); |
| 1031 | return Value.fromInterned((try mod.intern(.{ .un = .{ | 717 | return Value.fromInterned((try mod.intern(.{ .un = .{ |
| 1032 | .ty = ty.toIntern(), | 718 | .ty = ty.toIntern(), |
| 1033 | .tag = .none, | 719 | .tag = .none, |
| ... | @@ -1094,30 +780,19 @@ pub fn readFromPackedMemory( | ... | @@ -1094,30 +780,19 @@ pub fn readFromPackedMemory( |
| 1094 | return Value.true; | 780 | return Value.true; |
| 1095 | } | 781 | } |
| 1096 | }, | 782 | }, |
| 1097 | .Int, .Enum => |ty_tag| { | 783 | .Int => { |
| 1098 | if (buffer.len == 0) return mod.intValue(ty, 0); | 784 | if (buffer.len == 0) return mod.intValue(ty, 0); |
| 1099 | const int_info = ty.intInfo(mod); | 785 | const int_info = ty.intInfo(mod); |
| 1100 | const bits = int_info.bits; | 786 | const bits = int_info.bits; |
| 1101 | if (bits == 0) return mod.intValue(ty, 0); | 787 | if (bits == 0) return mod.intValue(ty, 0); |
| 1102 | 788 | ||
| 1103 | // Fast path for integers <= u64 | 789 | // Fast path for integers <= u64 |
| 1104 | if (bits <= 64) { | 790 | if (bits <= 64) switch (int_info.signedness) { |
| 1105 | const int_ty = switch (ty_tag) { | 791 | // Use different backing types for unsigned vs signed to avoid the need to go via |
| 1106 | .Int => ty, | 792 | // a larger type like `i128`. |
| 1107 | .Enum => ty.intTagType(mod), | 793 | .unsigned => return mod.intValue(ty, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)), |
| 1108 | else => unreachable, | 794 | .signed => return mod.intValue(ty, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)), |
| 1109 | }; | 795 | }; |
| 1110 | return mod.getCoerced(switch (int_info.signedness) { | ||
| 1111 | .signed => return mod.intValue( | ||
| 1112 | int_ty, | ||
| 1113 | std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed), | ||
| 1114 | ), | ||
| 1115 | .unsigned => return mod.intValue( | ||
| 1116 | int_ty, | ||
| 1117 | std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned), | ||
| 1118 | ), | ||
| 1119 | }, ty); | ||
| 1120 | } | ||
| 1121 | 796 | ||
| 1122 | // Slow path, we have to construct a big-int | 797 | // Slow path, we have to construct a big-int |
| 1123 | const abi_size = @as(usize, @intCast(ty.abiSize(mod))); | 798 | const abi_size = @as(usize, @intCast(ty.abiSize(mod))); |
| ... | @@ -1129,6 +804,11 @@ pub fn readFromPackedMemory( | ... | @@ -1129,6 +804,11 @@ pub fn readFromPackedMemory( |
| 1129 | bigint.readPackedTwosComplement(buffer, bit_offset, bits, endian, int_info.signedness); | 804 | bigint.readPackedTwosComplement(buffer, bit_offset, bits, endian, int_info.signedness); |
| 1130 | return mod.intValue_big(ty, bigint.toConst()); | 805 | return mod.intValue_big(ty, bigint.toConst()); |
| 1131 | }, | 806 | }, |
| 807 | .Enum => { | ||
| 808 | const int_ty = ty.intTagType(mod); | ||
| 809 | const int_val = try Value.readFromPackedMemory(int_ty, mod, buffer, bit_offset, arena); | ||
| 810 | return mod.getCoerced(int_val, ty); | ||
| 811 | }, | ||
| 1132 | .Float => return Value.fromInterned((try mod.intern(.{ .float = .{ | 812 | .Float => return Value.fromInterned((try mod.intern(.{ .float = .{ |
| 1133 | .ty = ty.toIntern(), | 813 | .ty = ty.toIntern(), |
| 1134 | .storage = switch (ty.floatBits(target)) { | 814 | .storage = switch (ty.floatBits(target)) { |
| ... | @@ -1149,7 +829,7 @@ pub fn readFromPackedMemory( | ... | @@ -1149,7 +829,7 @@ pub fn readFromPackedMemory( |
| 1149 | for (elems, 0..) |_, i| { | 829 | for (elems, 0..) |_, i| { |
| 1150 | // On big-endian systems, LLVM reverses the element order of vectors by default | 830 | // On big-endian systems, LLVM reverses the element order of vectors by default |
| 1151 | const tgt_elem_i = if (endian == .big) elems.len - i - 1 else i; | 831 | const tgt_elem_i = if (endian == .big) elems.len - i - 1 else i; |
| 1152 | elems[tgt_elem_i] = try (try readFromPackedMemory(elem_ty, mod, buffer, bit_offset + bits, arena)).intern(elem_ty, mod); | 832 | elems[tgt_elem_i] = (try readFromPackedMemory(elem_ty, mod, buffer, bit_offset + bits, arena)).toIntern(); |
| 1153 | bits += elem_bit_size; | 833 | bits += elem_bit_size; |
| 1154 | } | 834 | } |
| 1155 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 835 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| ... | @@ -1166,7 +846,7 @@ pub fn readFromPackedMemory( | ... | @@ -1166,7 +846,7 @@ pub fn readFromPackedMemory( |
| 1166 | for (field_vals, 0..) |*field_val, i| { | 846 | for (field_vals, 0..) |*field_val, i| { |
| 1167 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 847 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 1168 | const field_bits: u16 = @intCast(field_ty.bitSize(mod)); | 848 | const field_bits: u16 = @intCast(field_ty.bitSize(mod)); |
| 1169 | field_val.* = try (try readFromPackedMemory(field_ty, mod, buffer, bit_offset + bits, arena)).intern(field_ty, mod); | 849 | field_val.* = (try readFromPackedMemory(field_ty, mod, buffer, bit_offset + bits, arena)).toIntern(); |
| 1170 | bits += field_bits; | 850 | bits += field_bits; |
| 1171 | } | 851 | } |
| 1172 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 852 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| ... | @@ -1581,80 +1261,34 @@ pub fn slicePtr(val: Value, mod: *Module) Value { | ... | @@ -1581,80 +1261,34 @@ pub fn slicePtr(val: Value, mod: *Module) Value { |
| 1581 | return Value.fromInterned(mod.intern_pool.slicePtr(val.toIntern())); | 1261 | return Value.fromInterned(mod.intern_pool.slicePtr(val.toIntern())); |
| 1582 | } | 1262 | } |
| 1583 | 1263 | ||
| 1584 | pub fn sliceLen(val: Value, mod: *Module) u64 { | 1264 | /// Gets the `len` field of a slice value as a `u64`. |
| 1585 | const ip = &mod.intern_pool; | 1265 | /// Resolves the length using the provided `Sema` if necessary. |
| 1586 | return switch (ip.indexToKey(val.toIntern())) { | 1266 | pub fn sliceLen(val: Value, sema: *Sema) !u64 { |
| 1587 | .ptr => |ptr| switch (ip.indexToKey(switch (ptr.addr) { | 1267 | return Value.fromInterned(sema.mod.intern_pool.sliceLen(val.toIntern())).toUnsignedIntAdvanced(sema); |
| 1588 | .decl => |decl| mod.declPtr(decl).ty.toIntern(), | ||
| 1589 | .comptime_alloc => @panic("TODO"), | ||
| 1590 | .anon_decl => |anon_decl| ip.typeOf(anon_decl.val), | ||
| 1591 | .comptime_field => |comptime_field| ip.typeOf(comptime_field), | ||
| 1592 | else => unreachable, | ||
| 1593 | })) { | ||
| 1594 | .array_type => |array_type| array_type.len, | ||
| 1595 | else => 1, | ||
| 1596 | }, | ||
| 1597 | .slice => |slice| Value.fromInterned(slice.len).toUnsignedInt(mod), | ||
| 1598 | else => unreachable, | ||
| 1599 | }; | ||
| 1600 | } | 1268 | } |
| 1601 | 1269 | ||
| 1602 | /// Asserts the value is a single-item pointer to an array, or an array, | 1270 | /// Asserts the value is an aggregate, and returns the element value at the given index. |
| 1603 | /// or an unknown-length pointer, and returns the element value at the index. | 1271 | pub fn elemValue(val: Value, zcu: *Zcu, index: usize) Allocator.Error!Value { |
| 1604 | pub fn elemValue(val: Value, mod: *Module, index: usize) Allocator.Error!Value { | 1272 | const ip = &zcu.intern_pool; |
| 1605 | return (try val.maybeElemValue(mod, index)).?; | 1273 | switch (zcu.intern_pool.indexToKey(val.toIntern())) { |
| 1606 | } | 1274 | .undef => |ty| { |
| 1607 | 1275 | return Value.fromInterned(try zcu.intern(.{ .undef = Type.fromInterned(ty).childType(zcu).toIntern() })); | |
| 1608 | /// Like `elemValue`, but returns `null` instead of asserting on failure. | ||
| 1609 | pub fn maybeElemValue(val: Value, mod: *Module, index: usize) Allocator.Error!?Value { | ||
| 1610 | return val.maybeElemValueFull(null, mod, index); | ||
| 1611 | } | ||
| 1612 | |||
| 1613 | pub fn maybeElemValueFull(val: Value, sema: ?*Sema, mod: *Module, index: usize) Allocator.Error!?Value { | ||
| 1614 | return switch (val.ip_index) { | ||
| 1615 | .none => switch (val.tag()) { | ||
| 1616 | .bytes => try mod.intValue(Type.u8, val.castTag(.bytes).?.data[index]), | ||
| 1617 | .repeated => val.castTag(.repeated).?.data, | ||
| 1618 | .aggregate => val.castTag(.aggregate).?.data[index], | ||
| 1619 | .slice => val.castTag(.slice).?.data.ptr.maybeElemValueFull(sema, mod, index), | ||
| 1620 | else => null, | ||
| 1621 | }, | 1276 | }, |
| 1622 | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { | 1277 | .aggregate => |aggregate| { |
| 1623 | .undef => |ty| Value.fromInterned((try mod.intern(.{ | 1278 | const len = ip.aggregateTypeLen(aggregate.ty); |
| 1624 | .undef = Type.fromInterned(ty).elemType2(mod).toIntern(), | 1279 | if (index < len) return Value.fromInterned(switch (aggregate.storage) { |
| 1625 | }))), | 1280 | .bytes => |bytes| try zcu.intern(.{ .int = .{ |
| 1626 | .slice => |slice| return Value.fromInterned(slice.ptr).maybeElemValueFull(sema, mod, index), | 1281 | .ty = .u8_type, |
| 1627 | .ptr => |ptr| switch (ptr.addr) { | 1282 | .storage = .{ .u64 = bytes[index] }, |
| 1628 | .decl => |decl| mod.declPtr(decl).val.maybeElemValueFull(sema, mod, index), | 1283 | } }), |
| 1629 | .anon_decl => |anon_decl| Value.fromInterned(anon_decl.val).maybeElemValueFull(sema, mod, index), | 1284 | .elems => |elems| elems[index], |
| 1630 | .comptime_alloc => |idx| if (sema) |s| s.getComptimeAlloc(idx).val.maybeElemValueFull(sema, mod, index) else null, | 1285 | .repeated_elem => |elem| elem, |
| 1631 | .int, .eu_payload => null, | 1286 | }); |
| 1632 | .opt_payload => |base| Value.fromInterned(base).maybeElemValueFull(sema, mod, index), | 1287 | assert(index == len); |
| 1633 | .comptime_field => |field_val| Value.fromInterned(field_val).maybeElemValueFull(sema, mod, index), | 1288 | return Type.fromInterned(aggregate.ty).sentinel(zcu).?; |
| 1634 | .elem => |elem| Value.fromInterned(elem.base).maybeElemValueFull(sema, mod, index + @as(usize, @intCast(elem.index))), | ||
| 1635 | .field => |field| if (Value.fromInterned(field.base).pointerDecl(mod)) |decl_index| { | ||
| 1636 | const base_decl = mod.declPtr(decl_index); | ||
| 1637 | const field_val = try base_decl.val.fieldValue(mod, @as(usize, @intCast(field.index))); | ||
| 1638 | return field_val.maybeElemValueFull(sema, mod, index); | ||
| 1639 | } else null, | ||
| 1640 | }, | ||
| 1641 | .opt => |opt| Value.fromInterned(opt.val).maybeElemValueFull(sema, mod, index), | ||
| 1642 | .aggregate => |aggregate| { | ||
| 1643 | const len = mod.intern_pool.aggregateTypeLen(aggregate.ty); | ||
| 1644 | if (index < len) return Value.fromInterned(switch (aggregate.storage) { | ||
| 1645 | .bytes => |bytes| try mod.intern(.{ .int = .{ | ||
| 1646 | .ty = .u8_type, | ||
| 1647 | .storage = .{ .u64 = bytes[index] }, | ||
| 1648 | } }), | ||
| 1649 | .elems => |elems| elems[index], | ||
| 1650 | .repeated_elem => |elem| elem, | ||
| 1651 | }); | ||
| 1652 | assert(index == len); | ||
| 1653 | return Value.fromInterned(mod.intern_pool.indexToKey(aggregate.ty).array_type.sentinel); | ||
| 1654 | }, | ||
| 1655 | else => null, | ||
| 1656 | }, | 1289 | }, |
| 1657 | }; | 1290 | else => unreachable, |
| 1291 | } | ||
| 1658 | } | 1292 | } |
| 1659 | 1293 | ||
| 1660 | pub fn isLazyAlign(val: Value, mod: *Module) bool { | 1294 | pub fn isLazyAlign(val: Value, mod: *Module) bool { |
| ... | @@ -1686,83 +1320,48 @@ pub fn sliceArray( | ... | @@ -1686,83 +1320,48 @@ pub fn sliceArray( |
| 1686 | ) error{OutOfMemory}!Value { | 1320 | ) error{OutOfMemory}!Value { |
| 1687 | // TODO: write something like getCoercedInts to avoid needing to dupe | 1321 | // TODO: write something like getCoercedInts to avoid needing to dupe |
| 1688 | const mod = sema.mod; | 1322 | const mod = sema.mod; |
| 1689 | return switch (val.ip_index) { | 1323 | const aggregate = mod.intern_pool.indexToKey(val.toIntern()).aggregate; |
| 1690 | .none => switch (val.tag()) { | 1324 | return Value.fromInterned(try mod.intern(.{ .aggregate = .{ |
| 1691 | .slice => val.castTag(.slice).?.data.ptr.sliceArray(sema, start, end), | 1325 | .ty = switch (mod.intern_pool.indexToKey(mod.intern_pool.typeOf(val.toIntern()))) { |
| 1692 | .bytes => Tag.bytes.create(sema.arena, val.castTag(.bytes).?.data[start..end]), | 1326 | .array_type => |array_type| try mod.arrayType(.{ |
| 1693 | .repeated => val, | 1327 | .len = @as(u32, @intCast(end - start)), |
| 1694 | .aggregate => Tag.aggregate.create(sema.arena, val.castTag(.aggregate).?.data[start..end]), | 1328 | .child = array_type.child, |
| 1695 | else => unreachable, | 1329 | .sentinel = if (end == array_type.len) array_type.sentinel else .none, |
| 1696 | }, | 1330 | }), |
| 1697 | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { | 1331 | .vector_type => |vector_type| try mod.vectorType(.{ |
| 1698 | .ptr => |ptr| switch (ptr.addr) { | 1332 | .len = @as(u32, @intCast(end - start)), |
| 1699 | .decl => |decl| try mod.declPtr(decl).val.sliceArray(sema, start, end), | 1333 | .child = vector_type.child, |
| 1700 | .comptime_alloc => |idx| sema.getComptimeAlloc(idx).val.sliceArray(sema, start, end), | 1334 | }), |
| 1701 | .comptime_field => |comptime_field| Value.fromInterned(comptime_field) | ||
| 1702 | .sliceArray(sema, start, end), | ||
| 1703 | .elem => |elem| Value.fromInterned(elem.base) | ||
| 1704 | .sliceArray(sema, start + @as(usize, @intCast(elem.index)), end + @as(usize, @intCast(elem.index))), | ||
| 1705 | else => unreachable, | ||
| 1706 | }, | ||
| 1707 | .aggregate => |aggregate| Value.fromInterned((try mod.intern(.{ .aggregate = .{ | ||
| 1708 | .ty = switch (mod.intern_pool.indexToKey(mod.intern_pool.typeOf(val.toIntern()))) { | ||
| 1709 | .array_type => |array_type| try mod.arrayType(.{ | ||
| 1710 | .len = @as(u32, @intCast(end - start)), | ||
| 1711 | .child = array_type.child, | ||
| 1712 | .sentinel = if (end == array_type.len) array_type.sentinel else .none, | ||
| 1713 | }), | ||
| 1714 | .vector_type => |vector_type| try mod.vectorType(.{ | ||
| 1715 | .len = @as(u32, @intCast(end - start)), | ||
| 1716 | .child = vector_type.child, | ||
| 1717 | }), | ||
| 1718 | else => unreachable, | ||
| 1719 | }.toIntern(), | ||
| 1720 | .storage = switch (aggregate.storage) { | ||
| 1721 | .bytes => .{ .bytes = try sema.arena.dupe(u8, mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.bytes[start..end]) }, | ||
| 1722 | .elems => .{ .elems = try sema.arena.dupe(InternPool.Index, mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.elems[start..end]) }, | ||
| 1723 | .repeated_elem => |elem| .{ .repeated_elem = elem }, | ||
| 1724 | }, | ||
| 1725 | } }))), | ||
| 1726 | else => unreachable, | 1335 | else => unreachable, |
| 1336 | }.toIntern(), | ||
| 1337 | .storage = switch (aggregate.storage) { | ||
| 1338 | .bytes => .{ .bytes = try sema.arena.dupe(u8, mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.bytes[start..end]) }, | ||
| 1339 | .elems => .{ .elems = try sema.arena.dupe(InternPool.Index, mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage.elems[start..end]) }, | ||
| 1340 | .repeated_elem => |elem| .{ .repeated_elem = elem }, | ||
| 1727 | }, | 1341 | }, |
| 1728 | }; | 1342 | } })); |
| 1729 | } | 1343 | } |
| 1730 | 1344 | ||
| 1731 | pub fn fieldValue(val: Value, mod: *Module, index: usize) !Value { | 1345 | pub fn fieldValue(val: Value, mod: *Module, index: usize) !Value { |
| 1732 | return switch (val.ip_index) { | 1346 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1733 | .none => switch (val.tag()) { | 1347 | .undef => |ty| Value.fromInterned((try mod.intern(.{ |
| 1734 | .aggregate => { | 1348 | .undef = Type.fromInterned(ty).structFieldType(index, mod).toIntern(), |
| 1735 | const field_values = val.castTag(.aggregate).?.data; | 1349 | }))), |
| 1736 | return field_values[index]; | 1350 | .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) { |
| 1737 | }, | 1351 | .bytes => |bytes| try mod.intern(.{ .int = .{ |
| 1738 | .@"union" => { | 1352 | .ty = .u8_type, |
| 1739 | const payload = val.castTag(.@"union").?.data; | 1353 | .storage = .{ .u64 = bytes[index] }, |
| 1740 | // TODO assert the tag is correct | 1354 | } }), |
| 1741 | return payload.val; | 1355 | .elems => |elems| elems[index], |
| 1742 | }, | 1356 | .repeated_elem => |elem| elem, |
| 1743 | else => unreachable, | 1357 | }), |
| 1744 | }, | 1358 | // TODO assert the tag is correct |
| 1745 | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { | 1359 | .un => |un| Value.fromInterned(un.val), |
| 1746 | .undef => |ty| Value.fromInterned((try mod.intern(.{ | 1360 | else => unreachable, |
| 1747 | .undef = Type.fromInterned(ty).structFieldType(index, mod).toIntern(), | ||
| 1748 | }))), | ||
| 1749 | .aggregate => |aggregate| Value.fromInterned(switch (aggregate.storage) { | ||
| 1750 | .bytes => |bytes| try mod.intern(.{ .int = .{ | ||
| 1751 | .ty = .u8_type, | ||
| 1752 | .storage = .{ .u64 = bytes[index] }, | ||
| 1753 | } }), | ||
| 1754 | .elems => |elems| elems[index], | ||
| 1755 | .repeated_elem => |elem| elem, | ||
| 1756 | }), | ||
| 1757 | // TODO assert the tag is correct | ||
| 1758 | .un => |un| Value.fromInterned(un.val), | ||
| 1759 | else => unreachable, | ||
| 1760 | }, | ||
| 1761 | }; | 1361 | }; |
| 1762 | } | 1362 | } |
| 1763 | 1363 | ||
| 1764 | pub fn unionTag(val: Value, mod: *Module) ?Value { | 1364 | pub fn unionTag(val: Value, mod: *Module) ?Value { |
| 1765 | if (val.ip_index == .none) return val.castTag(.@"union").?.data.tag; | ||
| 1766 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | 1365 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1767 | .undef, .enum_tag => val, | 1366 | .undef, .enum_tag => val, |
| 1768 | .un => |un| if (un.tag != .none) Value.fromInterned(un.tag) else return null, | 1367 | .un => |un| if (un.tag != .none) Value.fromInterned(un.tag) else return null, |
| ... | @@ -1771,7 +1370,6 @@ pub fn unionTag(val: Value, mod: *Module) ?Value { | ... | @@ -1771,7 +1370,6 @@ pub fn unionTag(val: Value, mod: *Module) ?Value { |
| 1771 | } | 1370 | } |
| 1772 | 1371 | ||
| 1773 | pub fn unionValue(val: Value, mod: *Module) Value { | 1372 | pub fn unionValue(val: Value, mod: *Module) Value { |
| 1774 | if (val.ip_index == .none) return val.castTag(.@"union").?.data.val; | ||
| 1775 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | 1373 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 1776 | .un => |un| Value.fromInterned(un.val), | 1374 | .un => |un| Value.fromInterned(un.val), |
| 1777 | else => unreachable, | 1375 | else => unreachable, |
| ... | @@ -1792,7 +1390,7 @@ pub fn elemPtr( | ... | @@ -1792,7 +1390,7 @@ pub fn elemPtr( |
| 1792 | }; | 1390 | }; |
| 1793 | switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) { | 1391 | switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) { |
| 1794 | .ptr => |ptr| switch (ptr.addr) { | 1392 | .ptr => |ptr| switch (ptr.addr) { |
| 1795 | .elem => |elem| if (Type.fromInterned(mod.intern_pool.typeOf(elem.base)).elemType2(mod).eql(elem_ty, mod)) | 1393 | .elem => |elem| if (Value.fromInterned(elem.base).typeOf(mod).elemType2(mod).eql(elem_ty, mod)) |
| 1796 | return Value.fromInterned((try mod.intern(.{ .ptr = .{ | 1394 | return Value.fromInterned((try mod.intern(.{ .ptr = .{ |
| 1797 | .ty = elem_ptr_ty.toIntern(), | 1395 | .ty = elem_ptr_ty.toIntern(), |
| 1798 | .addr = .{ .elem = .{ | 1396 | .addr = .{ .elem = .{ |
| ... | @@ -1817,7 +1415,7 @@ pub fn elemPtr( | ... | @@ -1817,7 +1415,7 @@ pub fn elemPtr( |
| 1817 | } | 1415 | } |
| 1818 | 1416 | ||
| 1819 | pub fn isUndef(val: Value, mod: *Module) bool { | 1417 | pub fn isUndef(val: Value, mod: *Module) bool { |
| 1820 | return val.ip_index != .none and mod.intern_pool.isUndef(val.toIntern()); | 1418 | return mod.intern_pool.isUndef(val.toIntern()); |
| 1821 | } | 1419 | } |
| 1822 | 1420 | ||
| 1823 | /// TODO: check for cases such as array that is not marked undef but all the element | 1421 | /// TODO: check for cases such as array that is not marked undef but all the element |
| ... | @@ -1911,7 +1509,7 @@ pub fn floatFromIntAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty | ... | @@ -1911,7 +1509,7 @@ pub fn floatFromIntAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty |
| 1911 | const scalar_ty = float_ty.scalarType(mod); | 1509 | const scalar_ty = float_ty.scalarType(mod); |
| 1912 | for (result_data, 0..) |*scalar, i| { | 1510 | for (result_data, 0..) |*scalar, i| { |
| 1913 | const elem_val = try val.elemValue(mod, i); | 1511 | const elem_val = try val.elemValue(mod, i); |
| 1914 | scalar.* = try (try floatFromIntScalar(elem_val, scalar_ty, mod, opt_sema)).intern(scalar_ty, mod); | 1512 | scalar.* = (try floatFromIntScalar(elem_val, scalar_ty, mod, opt_sema)).toIntern(); |
| 1915 | } | 1513 | } |
| 1916 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1514 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 1917 | .ty = float_ty.toIntern(), | 1515 | .ty = float_ty.toIntern(), |
| ... | @@ -1989,7 +1587,7 @@ pub fn intAddSat( | ... | @@ -1989,7 +1587,7 @@ pub fn intAddSat( |
| 1989 | for (result_data, 0..) |*scalar, i| { | 1587 | for (result_data, 0..) |*scalar, i| { |
| 1990 | const lhs_elem = try lhs.elemValue(mod, i); | 1588 | const lhs_elem = try lhs.elemValue(mod, i); |
| 1991 | const rhs_elem = try rhs.elemValue(mod, i); | 1589 | const rhs_elem = try rhs.elemValue(mod, i); |
| 1992 | scalar.* = try (try intAddSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod); | 1590 | scalar.* = (try intAddSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); |
| 1993 | } | 1591 | } |
| 1994 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1592 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 1995 | .ty = ty.toIntern(), | 1593 | .ty = ty.toIntern(), |
| ... | @@ -2039,7 +1637,7 @@ pub fn intSubSat( | ... | @@ -2039,7 +1637,7 @@ pub fn intSubSat( |
| 2039 | for (result_data, 0..) |*scalar, i| { | 1637 | for (result_data, 0..) |*scalar, i| { |
| 2040 | const lhs_elem = try lhs.elemValue(mod, i); | 1638 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2041 | const rhs_elem = try rhs.elemValue(mod, i); | 1639 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2042 | scalar.* = try (try intSubSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod); | 1640 | scalar.* = (try intSubSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); |
| 2043 | } | 1641 | } |
| 2044 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1642 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2045 | .ty = ty.toIntern(), | 1643 | .ty = ty.toIntern(), |
| ... | @@ -2091,8 +1689,8 @@ pub fn intMulWithOverflow( | ... | @@ -2091,8 +1689,8 @@ pub fn intMulWithOverflow( |
| 2091 | const lhs_elem = try lhs.elemValue(mod, i); | 1689 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2092 | const rhs_elem = try rhs.elemValue(mod, i); | 1690 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2093 | const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod); | 1691 | const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod); |
| 2094 | of.* = try of_math_result.overflow_bit.intern(Type.u1, mod); | 1692 | of.* = of_math_result.overflow_bit.toIntern(); |
| 2095 | scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod); | 1693 | scalar.* = of_math_result.wrapped_result.toIntern(); |
| 2096 | } | 1694 | } |
| 2097 | return OverflowArithmeticResult{ | 1695 | return OverflowArithmeticResult{ |
| 2098 | .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1696 | .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| ... | @@ -2157,7 +1755,7 @@ pub fn numberMulWrap( | ... | @@ -2157,7 +1755,7 @@ pub fn numberMulWrap( |
| 2157 | for (result_data, 0..) |*scalar, i| { | 1755 | for (result_data, 0..) |*scalar, i| { |
| 2158 | const lhs_elem = try lhs.elemValue(mod, i); | 1756 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2159 | const rhs_elem = try rhs.elemValue(mod, i); | 1757 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2160 | scalar.* = try (try numberMulWrapScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod); | 1758 | scalar.* = (try numberMulWrapScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); |
| 2161 | } | 1759 | } |
| 2162 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1760 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2163 | .ty = ty.toIntern(), | 1761 | .ty = ty.toIntern(), |
| ... | @@ -2203,7 +1801,7 @@ pub fn intMulSat( | ... | @@ -2203,7 +1801,7 @@ pub fn intMulSat( |
| 2203 | for (result_data, 0..) |*scalar, i| { | 1801 | for (result_data, 0..) |*scalar, i| { |
| 2204 | const lhs_elem = try lhs.elemValue(mod, i); | 1802 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2205 | const rhs_elem = try rhs.elemValue(mod, i); | 1803 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2206 | scalar.* = try (try intMulSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod); | 1804 | scalar.* = (try intMulSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); |
| 2207 | } | 1805 | } |
| 2208 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1806 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2209 | .ty = ty.toIntern(), | 1807 | .ty = ty.toIntern(), |
| ... | @@ -2279,7 +1877,7 @@ pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value { | ... | @@ -2279,7 +1877,7 @@ pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value { |
| 2279 | const scalar_ty = ty.scalarType(mod); | 1877 | const scalar_ty = ty.scalarType(mod); |
| 2280 | for (result_data, 0..) |*scalar, i| { | 1878 | for (result_data, 0..) |*scalar, i| { |
| 2281 | const elem_val = try val.elemValue(mod, i); | 1879 | const elem_val = try val.elemValue(mod, i); |
| 2282 | scalar.* = try (try bitwiseNotScalar(elem_val, scalar_ty, arena, mod)).intern(scalar_ty, mod); | 1880 | scalar.* = (try bitwiseNotScalar(elem_val, scalar_ty, arena, mod)).toIntern(); |
| 2283 | } | 1881 | } |
| 2284 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1882 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2285 | .ty = ty.toIntern(), | 1883 | .ty = ty.toIntern(), |
| ... | @@ -2322,7 +1920,7 @@ pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: * | ... | @@ -2322,7 +1920,7 @@ pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: * |
| 2322 | for (result_data, 0..) |*scalar, i| { | 1920 | for (result_data, 0..) |*scalar, i| { |
| 2323 | const lhs_elem = try lhs.elemValue(mod, i); | 1921 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2324 | const rhs_elem = try rhs.elemValue(mod, i); | 1922 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2325 | scalar.* = try (try bitwiseAndScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod); | 1923 | scalar.* = (try bitwiseAndScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); |
| 2326 | } | 1924 | } |
| 2327 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1925 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2328 | .ty = ty.toIntern(), | 1926 | .ty = ty.toIntern(), |
| ... | @@ -2361,7 +1959,7 @@ pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Mod | ... | @@ -2361,7 +1959,7 @@ pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Mod |
| 2361 | for (result_data, 0..) |*scalar, i| { | 1959 | for (result_data, 0..) |*scalar, i| { |
| 2362 | const lhs_elem = try lhs.elemValue(mod, i); | 1960 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2363 | const rhs_elem = try rhs.elemValue(mod, i); | 1961 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2364 | scalar.* = try (try bitwiseNandScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod); | 1962 | scalar.* = (try bitwiseNandScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); |
| 2365 | } | 1963 | } |
| 2366 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1964 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2367 | .ty = ty.toIntern(), | 1965 | .ty = ty.toIntern(), |
| ... | @@ -2389,7 +1987,7 @@ pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M | ... | @@ -2389,7 +1987,7 @@ pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *M |
| 2389 | for (result_data, 0..) |*scalar, i| { | 1987 | for (result_data, 0..) |*scalar, i| { |
| 2390 | const lhs_elem = try lhs.elemValue(mod, i); | 1988 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2391 | const rhs_elem = try rhs.elemValue(mod, i); | 1989 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2392 | scalar.* = try (try bitwiseOrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod); | 1990 | scalar.* = (try bitwiseOrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); |
| 2393 | } | 1991 | } |
| 2394 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 1992 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2395 | .ty = ty.toIntern(), | 1993 | .ty = ty.toIntern(), |
| ... | @@ -2427,7 +2025,7 @@ pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: * | ... | @@ -2427,7 +2025,7 @@ pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: * |
| 2427 | for (result_data, 0..) |*scalar, i| { | 2025 | for (result_data, 0..) |*scalar, i| { |
| 2428 | const lhs_elem = try lhs.elemValue(mod, i); | 2026 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2429 | const rhs_elem = try rhs.elemValue(mod, i); | 2027 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2430 | scalar.* = try (try bitwiseXorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod); | 2028 | scalar.* = (try bitwiseXorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); |
| 2431 | } | 2029 | } |
| 2432 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2030 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2433 | .ty = ty.toIntern(), | 2031 | .ty = ty.toIntern(), |
| ... | @@ -2493,7 +2091,7 @@ fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator | ... | @@ -2493,7 +2091,7 @@ fn intDivInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator |
| 2493 | }, | 2091 | }, |
| 2494 | else => |e| return e, | 2092 | else => |e| return e, |
| 2495 | }; | 2093 | }; |
| 2496 | scalar.* = try val.intern(scalar_ty, mod); | 2094 | scalar.* = val.toIntern(); |
| 2497 | } | 2095 | } |
| 2498 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2096 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2499 | .ty = ty.toIntern(), | 2097 | .ty = ty.toIntern(), |
| ... | @@ -2541,7 +2139,7 @@ pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: | ... | @@ -2541,7 +2139,7 @@ pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: |
| 2541 | for (result_data, 0..) |*scalar, i| { | 2139 | for (result_data, 0..) |*scalar, i| { |
| 2542 | const lhs_elem = try lhs.elemValue(mod, i); | 2140 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2543 | const rhs_elem = try rhs.elemValue(mod, i); | 2141 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2544 | scalar.* = try (try intDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod); | 2142 | scalar.* = (try intDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); |
| 2545 | } | 2143 | } |
| 2546 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2144 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2547 | .ty = ty.toIntern(), | 2145 | .ty = ty.toIntern(), |
| ... | @@ -2583,7 +2181,7 @@ pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Modu | ... | @@ -2583,7 +2181,7 @@ pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Modu |
| 2583 | for (result_data, 0..) |*scalar, i| { | 2181 | for (result_data, 0..) |*scalar, i| { |
| 2584 | const lhs_elem = try lhs.elemValue(mod, i); | 2182 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2585 | const rhs_elem = try rhs.elemValue(mod, i); | 2183 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2586 | scalar.* = try (try intModScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod); | 2184 | scalar.* = (try intModScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); |
| 2587 | } | 2185 | } |
| 2588 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2186 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2589 | .ty = ty.toIntern(), | 2187 | .ty = ty.toIntern(), |
| ... | @@ -2620,7 +2218,6 @@ pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: | ... | @@ -2620,7 +2218,6 @@ pub fn intModScalar(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: |
| 2620 | 2218 | ||
| 2621 | /// Returns true if the value is a floating point type and is NaN. Returns false otherwise. | 2219 | /// Returns true if the value is a floating point type and is NaN. Returns false otherwise. |
| 2622 | pub fn isNan(val: Value, mod: *const Module) bool { | 2220 | pub fn isNan(val: Value, mod: *const Module) bool { |
| 2623 | if (val.ip_index == .none) return false; | ||
| 2624 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | 2221 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 2625 | .float => |float| switch (float.storage) { | 2222 | .float => |float| switch (float.storage) { |
| 2626 | inline else => |x| std.math.isNan(x), | 2223 | inline else => |x| std.math.isNan(x), |
| ... | @@ -2631,7 +2228,6 @@ pub fn isNan(val: Value, mod: *const Module) bool { | ... | @@ -2631,7 +2228,6 @@ pub fn isNan(val: Value, mod: *const Module) bool { |
| 2631 | 2228 | ||
| 2632 | /// Returns true if the value is a floating point type and is infinite. Returns false otherwise. | 2229 | /// Returns true if the value is a floating point type and is infinite. Returns false otherwise. |
| 2633 | pub fn isInf(val: Value, mod: *const Module) bool { | 2230 | pub fn isInf(val: Value, mod: *const Module) bool { |
| 2634 | if (val.ip_index == .none) return false; | ||
| 2635 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | 2231 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 2636 | .float => |float| switch (float.storage) { | 2232 | .float => |float| switch (float.storage) { |
| 2637 | inline else => |x| std.math.isInf(x), | 2233 | inline else => |x| std.math.isInf(x), |
| ... | @@ -2641,7 +2237,6 @@ pub fn isInf(val: Value, mod: *const Module) bool { | ... | @@ -2641,7 +2237,6 @@ pub fn isInf(val: Value, mod: *const Module) bool { |
| 2641 | } | 2237 | } |
| 2642 | 2238 | ||
| 2643 | pub fn isNegativeInf(val: Value, mod: *const Module) bool { | 2239 | pub fn isNegativeInf(val: Value, mod: *const Module) bool { |
| 2644 | if (val.ip_index == .none) return false; | ||
| 2645 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { | 2240 | return switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 2646 | .float => |float| switch (float.storage) { | 2241 | .float => |float| switch (float.storage) { |
| 2647 | inline else => |x| std.math.isNegativeInf(x), | 2242 | inline else => |x| std.math.isNegativeInf(x), |
| ... | @@ -2657,7 +2252,7 @@ pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: | ... | @@ -2657,7 +2252,7 @@ pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: |
| 2657 | for (result_data, 0..) |*scalar, i| { | 2252 | for (result_data, 0..) |*scalar, i| { |
| 2658 | const lhs_elem = try lhs.elemValue(mod, i); | 2253 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2659 | const rhs_elem = try rhs.elemValue(mod, i); | 2254 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2660 | scalar.* = try (try floatRemScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); | 2255 | scalar.* = (try floatRemScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 2661 | } | 2256 | } |
| 2662 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2257 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2663 | .ty = float_type.toIntern(), | 2258 | .ty = float_type.toIntern(), |
| ... | @@ -2690,7 +2285,7 @@ pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: | ... | @@ -2690,7 +2285,7 @@ pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: |
| 2690 | for (result_data, 0..) |*scalar, i| { | 2285 | for (result_data, 0..) |*scalar, i| { |
| 2691 | const lhs_elem = try lhs.elemValue(mod, i); | 2286 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2692 | const rhs_elem = try rhs.elemValue(mod, i); | 2287 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2693 | scalar.* = try (try floatModScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); | 2288 | scalar.* = (try floatModScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 2694 | } | 2289 | } |
| 2695 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2290 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2696 | .ty = float_type.toIntern(), | 2291 | .ty = float_type.toIntern(), |
| ... | @@ -2751,7 +2346,7 @@ fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator | ... | @@ -2751,7 +2346,7 @@ fn intMulInner(lhs: Value, rhs: Value, ty: Type, overflow_idx: *usize, allocator |
| 2751 | }, | 2346 | }, |
| 2752 | else => |e| return e, | 2347 | else => |e| return e, |
| 2753 | }; | 2348 | }; |
| 2754 | scalar.* = try val.intern(scalar_ty, mod); | 2349 | scalar.* = val.toIntern(); |
| 2755 | } | 2350 | } |
| 2756 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2351 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2757 | .ty = ty.toIntern(), | 2352 | .ty = ty.toIntern(), |
| ... | @@ -2793,7 +2388,7 @@ pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.buil | ... | @@ -2793,7 +2388,7 @@ pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.buil |
| 2793 | const scalar_ty = ty.scalarType(mod); | 2388 | const scalar_ty = ty.scalarType(mod); |
| 2794 | for (result_data, 0..) |*scalar, i| { | 2389 | for (result_data, 0..) |*scalar, i| { |
| 2795 | const elem_val = try val.elemValue(mod, i); | 2390 | const elem_val = try val.elemValue(mod, i); |
| 2796 | scalar.* = try (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, bits, mod)).intern(scalar_ty, mod); | 2391 | scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, bits, mod)).toIntern(); |
| 2797 | } | 2392 | } |
| 2798 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2393 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2799 | .ty = ty.toIntern(), | 2394 | .ty = ty.toIntern(), |
| ... | @@ -2818,7 +2413,7 @@ pub fn intTruncBitsAsValue( | ... | @@ -2818,7 +2413,7 @@ pub fn intTruncBitsAsValue( |
| 2818 | for (result_data, 0..) |*scalar, i| { | 2413 | for (result_data, 0..) |*scalar, i| { |
| 2819 | const elem_val = try val.elemValue(mod, i); | 2414 | const elem_val = try val.elemValue(mod, i); |
| 2820 | const bits_elem = try bits.elemValue(mod, i); | 2415 | const bits_elem = try bits.elemValue(mod, i); |
| 2821 | scalar.* = try (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, @as(u16, @intCast(bits_elem.toUnsignedInt(mod))), mod)).intern(scalar_ty, mod); | 2416 | scalar.* = (try intTruncScalar(elem_val, scalar_ty, allocator, signedness, @as(u16, @intCast(bits_elem.toUnsignedInt(mod))), mod)).toIntern(); |
| 2822 | } | 2417 | } |
| 2823 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2418 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2824 | .ty = ty.toIntern(), | 2419 | .ty = ty.toIntern(), |
| ... | @@ -2858,7 +2453,7 @@ pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) | ... | @@ -2858,7 +2453,7 @@ pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) |
| 2858 | for (result_data, 0..) |*scalar, i| { | 2453 | for (result_data, 0..) |*scalar, i| { |
| 2859 | const lhs_elem = try lhs.elemValue(mod, i); | 2454 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2860 | const rhs_elem = try rhs.elemValue(mod, i); | 2455 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2861 | scalar.* = try (try shlScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod); | 2456 | scalar.* = (try shlScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); |
| 2862 | } | 2457 | } |
| 2863 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2458 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2864 | .ty = ty.toIntern(), | 2459 | .ty = ty.toIntern(), |
| ... | @@ -2908,8 +2503,8 @@ pub fn shlWithOverflow( | ... | @@ -2908,8 +2503,8 @@ pub fn shlWithOverflow( |
| 2908 | const lhs_elem = try lhs.elemValue(mod, i); | 2503 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2909 | const rhs_elem = try rhs.elemValue(mod, i); | 2504 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2910 | const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod); | 2505 | const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod); |
| 2911 | of.* = try of_math_result.overflow_bit.intern(Type.u1, mod); | 2506 | of.* = of_math_result.overflow_bit.toIntern(); |
| 2912 | scalar.* = try of_math_result.wrapped_result.intern(scalar_ty, mod); | 2507 | scalar.* = of_math_result.wrapped_result.toIntern(); |
| 2913 | } | 2508 | } |
| 2914 | return OverflowArithmeticResult{ | 2509 | return OverflowArithmeticResult{ |
| 2915 | .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2510 | .overflow_bit = Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| ... | @@ -2969,7 +2564,7 @@ pub fn shlSat( | ... | @@ -2969,7 +2564,7 @@ pub fn shlSat( |
| 2969 | for (result_data, 0..) |*scalar, i| { | 2564 | for (result_data, 0..) |*scalar, i| { |
| 2970 | const lhs_elem = try lhs.elemValue(mod, i); | 2565 | const lhs_elem = try lhs.elemValue(mod, i); |
| 2971 | const rhs_elem = try rhs.elemValue(mod, i); | 2566 | const rhs_elem = try rhs.elemValue(mod, i); |
| 2972 | scalar.* = try (try shlSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod); | 2567 | scalar.* = (try shlSatScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); |
| 2973 | } | 2568 | } |
| 2974 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2569 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 2975 | .ty = ty.toIntern(), | 2570 | .ty = ty.toIntern(), |
| ... | @@ -3019,7 +2614,7 @@ pub fn shlTrunc( | ... | @@ -3019,7 +2614,7 @@ pub fn shlTrunc( |
| 3019 | for (result_data, 0..) |*scalar, i| { | 2614 | for (result_data, 0..) |*scalar, i| { |
| 3020 | const lhs_elem = try lhs.elemValue(mod, i); | 2615 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3021 | const rhs_elem = try rhs.elemValue(mod, i); | 2616 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3022 | scalar.* = try (try shlTruncScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).intern(scalar_ty, mod); | 2617 | scalar.* = (try shlTruncScalar(lhs_elem, rhs_elem, scalar_ty, arena, mod)).toIntern(); |
| 3023 | } | 2618 | } |
| 3024 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2619 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3025 | .ty = ty.toIntern(), | 2620 | .ty = ty.toIntern(), |
| ... | @@ -3049,7 +2644,7 @@ pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) | ... | @@ -3049,7 +2644,7 @@ pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) |
| 3049 | for (result_data, 0..) |*scalar, i| { | 2644 | for (result_data, 0..) |*scalar, i| { |
| 3050 | const lhs_elem = try lhs.elemValue(mod, i); | 2645 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3051 | const rhs_elem = try rhs.elemValue(mod, i); | 2646 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3052 | scalar.* = try (try shrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).intern(scalar_ty, mod); | 2647 | scalar.* = (try shrScalar(lhs_elem, rhs_elem, scalar_ty, allocator, mod)).toIntern(); |
| 3053 | } | 2648 | } |
| 3054 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2649 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3055 | .ty = ty.toIntern(), | 2650 | .ty = ty.toIntern(), |
| ... | @@ -3101,7 +2696,7 @@ pub fn floatNeg( | ... | @@ -3101,7 +2696,7 @@ pub fn floatNeg( |
| 3101 | const scalar_ty = float_type.scalarType(mod); | 2696 | const scalar_ty = float_type.scalarType(mod); |
| 3102 | for (result_data, 0..) |*scalar, i| { | 2697 | for (result_data, 0..) |*scalar, i| { |
| 3103 | const elem_val = try val.elemValue(mod, i); | 2698 | const elem_val = try val.elemValue(mod, i); |
| 3104 | scalar.* = try (try floatNegScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); | 2699 | scalar.* = (try floatNegScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3105 | } | 2700 | } |
| 3106 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2701 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3107 | .ty = float_type.toIntern(), | 2702 | .ty = float_type.toIntern(), |
| ... | @@ -3144,7 +2739,7 @@ pub fn floatAdd( | ... | @@ -3144,7 +2739,7 @@ pub fn floatAdd( |
| 3144 | for (result_data, 0..) |*scalar, i| { | 2739 | for (result_data, 0..) |*scalar, i| { |
| 3145 | const lhs_elem = try lhs.elemValue(mod, i); | 2740 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3146 | const rhs_elem = try rhs.elemValue(mod, i); | 2741 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3147 | scalar.* = try (try floatAddScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); | 2742 | scalar.* = (try floatAddScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 3148 | } | 2743 | } |
| 3149 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2744 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3150 | .ty = float_type.toIntern(), | 2745 | .ty = float_type.toIntern(), |
| ... | @@ -3188,7 +2783,7 @@ pub fn floatSub( | ... | @@ -3188,7 +2783,7 @@ pub fn floatSub( |
| 3188 | for (result_data, 0..) |*scalar, i| { | 2783 | for (result_data, 0..) |*scalar, i| { |
| 3189 | const lhs_elem = try lhs.elemValue(mod, i); | 2784 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3190 | const rhs_elem = try rhs.elemValue(mod, i); | 2785 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3191 | scalar.* = try (try floatSubScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); | 2786 | scalar.* = (try floatSubScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 3192 | } | 2787 | } |
| 3193 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2788 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3194 | .ty = float_type.toIntern(), | 2789 | .ty = float_type.toIntern(), |
| ... | @@ -3232,7 +2827,7 @@ pub fn floatDiv( | ... | @@ -3232,7 +2827,7 @@ pub fn floatDiv( |
| 3232 | for (result_data, 0..) |*scalar, i| { | 2827 | for (result_data, 0..) |*scalar, i| { |
| 3233 | const lhs_elem = try lhs.elemValue(mod, i); | 2828 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3234 | const rhs_elem = try rhs.elemValue(mod, i); | 2829 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3235 | scalar.* = try (try floatDivScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); | 2830 | scalar.* = (try floatDivScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 3236 | } | 2831 | } |
| 3237 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2832 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3238 | .ty = float_type.toIntern(), | 2833 | .ty = float_type.toIntern(), |
| ... | @@ -3276,7 +2871,7 @@ pub fn floatDivFloor( | ... | @@ -3276,7 +2871,7 @@ pub fn floatDivFloor( |
| 3276 | for (result_data, 0..) |*scalar, i| { | 2871 | for (result_data, 0..) |*scalar, i| { |
| 3277 | const lhs_elem = try lhs.elemValue(mod, i); | 2872 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3278 | const rhs_elem = try rhs.elemValue(mod, i); | 2873 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3279 | scalar.* = try (try floatDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); | 2874 | scalar.* = (try floatDivFloorScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 3280 | } | 2875 | } |
| 3281 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2876 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3282 | .ty = float_type.toIntern(), | 2877 | .ty = float_type.toIntern(), |
| ... | @@ -3320,7 +2915,7 @@ pub fn floatDivTrunc( | ... | @@ -3320,7 +2915,7 @@ pub fn floatDivTrunc( |
| 3320 | for (result_data, 0..) |*scalar, i| { | 2915 | for (result_data, 0..) |*scalar, i| { |
| 3321 | const lhs_elem = try lhs.elemValue(mod, i); | 2916 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3322 | const rhs_elem = try rhs.elemValue(mod, i); | 2917 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3323 | scalar.* = try (try floatDivTruncScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); | 2918 | scalar.* = (try floatDivTruncScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 3324 | } | 2919 | } |
| 3325 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2920 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3326 | .ty = float_type.toIntern(), | 2921 | .ty = float_type.toIntern(), |
| ... | @@ -3364,7 +2959,7 @@ pub fn floatMul( | ... | @@ -3364,7 +2959,7 @@ pub fn floatMul( |
| 3364 | for (result_data, 0..) |*scalar, i| { | 2959 | for (result_data, 0..) |*scalar, i| { |
| 3365 | const lhs_elem = try lhs.elemValue(mod, i); | 2960 | const lhs_elem = try lhs.elemValue(mod, i); |
| 3366 | const rhs_elem = try rhs.elemValue(mod, i); | 2961 | const rhs_elem = try rhs.elemValue(mod, i); |
| 3367 | scalar.* = try (try floatMulScalar(lhs_elem, rhs_elem, scalar_ty, mod)).intern(scalar_ty, mod); | 2962 | scalar.* = (try floatMulScalar(lhs_elem, rhs_elem, scalar_ty, mod)).toIntern(); |
| 3368 | } | 2963 | } |
| 3369 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 2964 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3370 | .ty = float_type.toIntern(), | 2965 | .ty = float_type.toIntern(), |
| ... | @@ -3401,7 +2996,7 @@ pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value | ... | @@ -3401,7 +2996,7 @@ pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3401 | const scalar_ty = float_type.scalarType(mod); | 2996 | const scalar_ty = float_type.scalarType(mod); |
| 3402 | for (result_data, 0..) |*scalar, i| { | 2997 | for (result_data, 0..) |*scalar, i| { |
| 3403 | const elem_val = try val.elemValue(mod, i); | 2998 | const elem_val = try val.elemValue(mod, i); |
| 3404 | scalar.* = try (try sqrtScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); | 2999 | scalar.* = (try sqrtScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3405 | } | 3000 | } |
| 3406 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3001 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3407 | .ty = float_type.toIntern(), | 3002 | .ty = float_type.toIntern(), |
| ... | @@ -3433,7 +3028,7 @@ pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value | ... | @@ -3433,7 +3028,7 @@ pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3433 | const scalar_ty = float_type.scalarType(mod); | 3028 | const scalar_ty = float_type.scalarType(mod); |
| 3434 | for (result_data, 0..) |*scalar, i| { | 3029 | for (result_data, 0..) |*scalar, i| { |
| 3435 | const elem_val = try val.elemValue(mod, i); | 3030 | const elem_val = try val.elemValue(mod, i); |
| 3436 | scalar.* = try (try sinScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); | 3031 | scalar.* = (try sinScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3437 | } | 3032 | } |
| 3438 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3033 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3439 | .ty = float_type.toIntern(), | 3034 | .ty = float_type.toIntern(), |
| ... | @@ -3465,7 +3060,7 @@ pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value | ... | @@ -3465,7 +3060,7 @@ pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3465 | const scalar_ty = float_type.scalarType(mod); | 3060 | const scalar_ty = float_type.scalarType(mod); |
| 3466 | for (result_data, 0..) |*scalar, i| { | 3061 | for (result_data, 0..) |*scalar, i| { |
| 3467 | const elem_val = try val.elemValue(mod, i); | 3062 | const elem_val = try val.elemValue(mod, i); |
| 3468 | scalar.* = try (try cosScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); | 3063 | scalar.* = (try cosScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3469 | } | 3064 | } |
| 3470 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3065 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3471 | .ty = float_type.toIntern(), | 3066 | .ty = float_type.toIntern(), |
| ... | @@ -3497,7 +3092,7 @@ pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value | ... | @@ -3497,7 +3092,7 @@ pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3497 | const scalar_ty = float_type.scalarType(mod); | 3092 | const scalar_ty = float_type.scalarType(mod); |
| 3498 | for (result_data, 0..) |*scalar, i| { | 3093 | for (result_data, 0..) |*scalar, i| { |
| 3499 | const elem_val = try val.elemValue(mod, i); | 3094 | const elem_val = try val.elemValue(mod, i); |
| 3500 | scalar.* = try (try tanScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); | 3095 | scalar.* = (try tanScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3501 | } | 3096 | } |
| 3502 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3097 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3503 | .ty = float_type.toIntern(), | 3098 | .ty = float_type.toIntern(), |
| ... | @@ -3529,7 +3124,7 @@ pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value | ... | @@ -3529,7 +3124,7 @@ pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3529 | const scalar_ty = float_type.scalarType(mod); | 3124 | const scalar_ty = float_type.scalarType(mod); |
| 3530 | for (result_data, 0..) |*scalar, i| { | 3125 | for (result_data, 0..) |*scalar, i| { |
| 3531 | const elem_val = try val.elemValue(mod, i); | 3126 | const elem_val = try val.elemValue(mod, i); |
| 3532 | scalar.* = try (try expScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); | 3127 | scalar.* = (try expScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3533 | } | 3128 | } |
| 3534 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3129 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3535 | .ty = float_type.toIntern(), | 3130 | .ty = float_type.toIntern(), |
| ... | @@ -3561,7 +3156,7 @@ pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value | ... | @@ -3561,7 +3156,7 @@ pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3561 | const scalar_ty = float_type.scalarType(mod); | 3156 | const scalar_ty = float_type.scalarType(mod); |
| 3562 | for (result_data, 0..) |*scalar, i| { | 3157 | for (result_data, 0..) |*scalar, i| { |
| 3563 | const elem_val = try val.elemValue(mod, i); | 3158 | const elem_val = try val.elemValue(mod, i); |
| 3564 | scalar.* = try (try exp2Scalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); | 3159 | scalar.* = (try exp2Scalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3565 | } | 3160 | } |
| 3566 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3161 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3567 | .ty = float_type.toIntern(), | 3162 | .ty = float_type.toIntern(), |
| ... | @@ -3593,7 +3188,7 @@ pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value | ... | @@ -3593,7 +3188,7 @@ pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3593 | const scalar_ty = float_type.scalarType(mod); | 3188 | const scalar_ty = float_type.scalarType(mod); |
| 3594 | for (result_data, 0..) |*scalar, i| { | 3189 | for (result_data, 0..) |*scalar, i| { |
| 3595 | const elem_val = try val.elemValue(mod, i); | 3190 | const elem_val = try val.elemValue(mod, i); |
| 3596 | scalar.* = try (try logScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); | 3191 | scalar.* = (try logScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3597 | } | 3192 | } |
| 3598 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3193 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3599 | .ty = float_type.toIntern(), | 3194 | .ty = float_type.toIntern(), |
| ... | @@ -3625,7 +3220,7 @@ pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value | ... | @@ -3625,7 +3220,7 @@ pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3625 | const scalar_ty = float_type.scalarType(mod); | 3220 | const scalar_ty = float_type.scalarType(mod); |
| 3626 | for (result_data, 0..) |*scalar, i| { | 3221 | for (result_data, 0..) |*scalar, i| { |
| 3627 | const elem_val = try val.elemValue(mod, i); | 3222 | const elem_val = try val.elemValue(mod, i); |
| 3628 | scalar.* = try (try log2Scalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); | 3223 | scalar.* = (try log2Scalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3629 | } | 3224 | } |
| 3630 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3225 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3631 | .ty = float_type.toIntern(), | 3226 | .ty = float_type.toIntern(), |
| ... | @@ -3657,7 +3252,7 @@ pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu | ... | @@ -3657,7 +3252,7 @@ pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu |
| 3657 | const scalar_ty = float_type.scalarType(mod); | 3252 | const scalar_ty = float_type.scalarType(mod); |
| 3658 | for (result_data, 0..) |*scalar, i| { | 3253 | for (result_data, 0..) |*scalar, i| { |
| 3659 | const elem_val = try val.elemValue(mod, i); | 3254 | const elem_val = try val.elemValue(mod, i); |
| 3660 | scalar.* = try (try log10Scalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); | 3255 | scalar.* = (try log10Scalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3661 | } | 3256 | } |
| 3662 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3257 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3663 | .ty = float_type.toIntern(), | 3258 | .ty = float_type.toIntern(), |
| ... | @@ -3689,7 +3284,7 @@ pub fn abs(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value { | ... | @@ -3689,7 +3284,7 @@ pub fn abs(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value { |
| 3689 | const scalar_ty = ty.scalarType(mod); | 3284 | const scalar_ty = ty.scalarType(mod); |
| 3690 | for (result_data, 0..) |*scalar, i| { | 3285 | for (result_data, 0..) |*scalar, i| { |
| 3691 | const elem_val = try val.elemValue(mod, i); | 3286 | const elem_val = try val.elemValue(mod, i); |
| 3692 | scalar.* = try (try absScalar(elem_val, scalar_ty, mod, arena)).intern(scalar_ty, mod); | 3287 | scalar.* = (try absScalar(elem_val, scalar_ty, mod, arena)).toIntern(); |
| 3693 | } | 3288 | } |
| 3694 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3289 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3695 | .ty = ty.toIntern(), | 3290 | .ty = ty.toIntern(), |
| ... | @@ -3740,7 +3335,7 @@ pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu | ... | @@ -3740,7 +3335,7 @@ pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu |
| 3740 | const scalar_ty = float_type.scalarType(mod); | 3335 | const scalar_ty = float_type.scalarType(mod); |
| 3741 | for (result_data, 0..) |*scalar, i| { | 3336 | for (result_data, 0..) |*scalar, i| { |
| 3742 | const elem_val = try val.elemValue(mod, i); | 3337 | const elem_val = try val.elemValue(mod, i); |
| 3743 | scalar.* = try (try floorScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); | 3338 | scalar.* = (try floorScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3744 | } | 3339 | } |
| 3745 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3340 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3746 | .ty = float_type.toIntern(), | 3341 | .ty = float_type.toIntern(), |
| ... | @@ -3772,7 +3367,7 @@ pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value | ... | @@ -3772,7 +3367,7 @@ pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value |
| 3772 | const scalar_ty = float_type.scalarType(mod); | 3367 | const scalar_ty = float_type.scalarType(mod); |
| 3773 | for (result_data, 0..) |*scalar, i| { | 3368 | for (result_data, 0..) |*scalar, i| { |
| 3774 | const elem_val = try val.elemValue(mod, i); | 3369 | const elem_val = try val.elemValue(mod, i); |
| 3775 | scalar.* = try (try ceilScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); | 3370 | scalar.* = (try ceilScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3776 | } | 3371 | } |
| 3777 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3372 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3778 | .ty = float_type.toIntern(), | 3373 | .ty = float_type.toIntern(), |
| ... | @@ -3804,7 +3399,7 @@ pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu | ... | @@ -3804,7 +3399,7 @@ pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu |
| 3804 | const scalar_ty = float_type.scalarType(mod); | 3399 | const scalar_ty = float_type.scalarType(mod); |
| 3805 | for (result_data, 0..) |*scalar, i| { | 3400 | for (result_data, 0..) |*scalar, i| { |
| 3806 | const elem_val = try val.elemValue(mod, i); | 3401 | const elem_val = try val.elemValue(mod, i); |
| 3807 | scalar.* = try (try roundScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); | 3402 | scalar.* = (try roundScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3808 | } | 3403 | } |
| 3809 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3404 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3810 | .ty = float_type.toIntern(), | 3405 | .ty = float_type.toIntern(), |
| ... | @@ -3836,7 +3431,7 @@ pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu | ... | @@ -3836,7 +3431,7 @@ pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Valu |
| 3836 | const scalar_ty = float_type.scalarType(mod); | 3431 | const scalar_ty = float_type.scalarType(mod); |
| 3837 | for (result_data, 0..) |*scalar, i| { | 3432 | for (result_data, 0..) |*scalar, i| { |
| 3838 | const elem_val = try val.elemValue(mod, i); | 3433 | const elem_val = try val.elemValue(mod, i); |
| 3839 | scalar.* = try (try truncScalar(elem_val, scalar_ty, mod)).intern(scalar_ty, mod); | 3434 | scalar.* = (try truncScalar(elem_val, scalar_ty, mod)).toIntern(); |
| 3840 | } | 3435 | } |
| 3841 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3436 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3842 | .ty = float_type.toIntern(), | 3437 | .ty = float_type.toIntern(), |
| ... | @@ -3877,7 +3472,7 @@ pub fn mulAdd( | ... | @@ -3877,7 +3472,7 @@ pub fn mulAdd( |
| 3877 | const mulend1_elem = try mulend1.elemValue(mod, i); | 3472 | const mulend1_elem = try mulend1.elemValue(mod, i); |
| 3878 | const mulend2_elem = try mulend2.elemValue(mod, i); | 3473 | const mulend2_elem = try mulend2.elemValue(mod, i); |
| 3879 | const addend_elem = try addend.elemValue(mod, i); | 3474 | const addend_elem = try addend.elemValue(mod, i); |
| 3880 | scalar.* = try (try mulAddScalar(scalar_ty, mulend1_elem, mulend2_elem, addend_elem, mod)).intern(scalar_ty, mod); | 3475 | scalar.* = (try mulAddScalar(scalar_ty, mulend1_elem, mulend2_elem, addend_elem, mod)).toIntern(); |
| 3881 | } | 3476 | } |
| 3882 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 3477 | return Value.fromInterned((try mod.intern(.{ .aggregate = .{ |
| 3883 | .ty = float_type.toIntern(), | 3478 | .ty = float_type.toIntern(), |
| ... | @@ -3939,6 +3534,10 @@ pub fn isGenericPoison(val: Value) bool { | ... | @@ -3939,6 +3534,10 @@ pub fn isGenericPoison(val: Value) bool { |
| 3939 | return val.toIntern() == .generic_poison; | 3534 | return val.toIntern() == .generic_poison; |
| 3940 | } | 3535 | } |
| 3941 | 3536 | ||
| 3537 | pub fn typeOf(val: Value, zcu: *const Zcu) Type { | ||
| 3538 | return Type.fromInterned(zcu.intern_pool.typeOf(val.toIntern())); | ||
| 3539 | } | ||
| 3540 | |||
| 3942 | /// For an integer (comptime or fixed-width) `val`, returns the comptime-known bounds of the value. | 3541 | /// For an integer (comptime or fixed-width) `val`, returns the comptime-known bounds of the value. |
| 3943 | /// If `val` is not undef, the bounds are both `val`. | 3542 | /// If `val` is not undef, the bounds are both `val`. |
| 3944 | /// If `val` is undef and has a fixed-width type, the bounds are the bounds of the type. | 3543 | /// If `val` is undef and has a fixed-width type, the bounds are the bounds of the type. |
| ... | @@ -3953,98 +3552,26 @@ pub fn intValueBounds(val: Value, mod: *Module) !?[2]Value { | ... | @@ -3953,98 +3552,26 @@ pub fn intValueBounds(val: Value, mod: *Module) !?[2]Value { |
| 3953 | }; | 3552 | }; |
| 3954 | } | 3553 | } |
| 3955 | 3554 | ||
| 3956 | /// This type is not copyable since it may contain pointers to its inner data. | ||
| 3957 | pub const Payload = struct { | ||
| 3958 | tag: Tag, | ||
| 3959 | |||
| 3960 | pub const Slice = struct { | ||
| 3961 | base: Payload, | ||
| 3962 | data: struct { | ||
| 3963 | ptr: Value, | ||
| 3964 | len: Value, | ||
| 3965 | }, | ||
| 3966 | }; | ||
| 3967 | |||
| 3968 | pub const Bytes = struct { | ||
| 3969 | base: Payload, | ||
| 3970 | /// Includes the sentinel, if any. | ||
| 3971 | data: []const u8, | ||
| 3972 | }; | ||
| 3973 | |||
| 3974 | pub const SubValue = struct { | ||
| 3975 | base: Payload, | ||
| 3976 | data: Value, | ||
| 3977 | }; | ||
| 3978 | |||
| 3979 | pub const Aggregate = struct { | ||
| 3980 | base: Payload, | ||
| 3981 | /// Field values. The types are according to the struct or array type. | ||
| 3982 | /// The length is provided here so that copying a Value does not depend on the Type. | ||
| 3983 | data: []Value, | ||
| 3984 | }; | ||
| 3985 | |||
| 3986 | pub const Union = struct { | ||
| 3987 | pub const base_tag = Tag.@"union"; | ||
| 3988 | |||
| 3989 | base: Payload = .{ .tag = base_tag }, | ||
| 3990 | data: Data, | ||
| 3991 | |||
| 3992 | pub const Data = struct { | ||
| 3993 | tag: ?Value, | ||
| 3994 | val: Value, | ||
| 3995 | }; | ||
| 3996 | }; | ||
| 3997 | }; | ||
| 3998 | |||
| 3999 | pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace; | 3555 | pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace; |
| 4000 | 3556 | ||
| 4001 | pub const zero_usize: Value = .{ .ip_index = .zero_usize, .legacy = undefined }; | 3557 | pub const zero_usize: Value = .{ .ip_index = .zero_usize }; |
| 4002 | pub const zero_u8: Value = .{ .ip_index = .zero_u8, .legacy = undefined }; | 3558 | pub const zero_u8: Value = .{ .ip_index = .zero_u8 }; |
| 4003 | pub const zero_comptime_int: Value = .{ .ip_index = .zero, .legacy = undefined }; | 3559 | pub const zero_comptime_int: Value = .{ .ip_index = .zero }; |
| 4004 | pub const one_comptime_int: Value = .{ .ip_index = .one, .legacy = undefined }; | 3560 | pub const one_comptime_int: Value = .{ .ip_index = .one }; |
| 4005 | pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one, .legacy = undefined }; | 3561 | pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one }; |
| 4006 | pub const undef: Value = .{ .ip_index = .undef, .legacy = undefined }; | 3562 | pub const undef: Value = .{ .ip_index = .undef }; |
| 4007 | pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined }; | 3563 | pub const @"void": Value = .{ .ip_index = .void_value }; |
| 4008 | pub const @"null": Value = .{ .ip_index = .null_value, .legacy = undefined }; | 3564 | pub const @"null": Value = .{ .ip_index = .null_value }; |
| 4009 | pub const @"false": Value = .{ .ip_index = .bool_false, .legacy = undefined }; | 3565 | pub const @"false": Value = .{ .ip_index = .bool_false }; |
| 4010 | pub const @"true": Value = .{ .ip_index = .bool_true, .legacy = undefined }; | 3566 | pub const @"true": Value = .{ .ip_index = .bool_true }; |
| 4011 | pub const @"unreachable": Value = .{ .ip_index = .unreachable_value, .legacy = undefined }; | 3567 | pub const @"unreachable": Value = .{ .ip_index = .unreachable_value }; |
| 4012 | 3568 | ||
| 4013 | pub const generic_poison: Value = .{ .ip_index = .generic_poison, .legacy = undefined }; | 3569 | pub const generic_poison: Value = .{ .ip_index = .generic_poison }; |
| 4014 | pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type, .legacy = undefined }; | 3570 | pub const generic_poison_type: Value = .{ .ip_index = .generic_poison_type }; |
| 4015 | pub const empty_struct: Value = .{ .ip_index = .empty_struct, .legacy = undefined }; | 3571 | pub const empty_struct: Value = .{ .ip_index = .empty_struct }; |
| 4016 | 3572 | ||
| 4017 | pub fn makeBool(x: bool) Value { | 3573 | pub fn makeBool(x: bool) Value { |
| 4018 | return if (x) Value.true else Value.false; | 3574 | return if (x) Value.true else Value.false; |
| 4019 | } | 3575 | } |
| 4020 | 3576 | ||
| 4021 | pub const RuntimeIndex = InternPool.RuntimeIndex; | 3577 | pub const RuntimeIndex = InternPool.RuntimeIndex; |
| 4022 | |||
| 4023 | /// This function is used in the debugger pretty formatters in tools/ to fetch the | ||
| 4024 | /// Tag to Payload mapping to facilitate fancy debug printing for this type. | ||
| 4025 | fn dbHelper(self: *Value, tag_to_payload_map: *map: { | ||
| 4026 | const tags = @typeInfo(Tag).Enum.fields; | ||
| 4027 | var fields: [tags.len]std.builtin.Type.StructField = undefined; | ||
| 4028 | for (&fields, tags) |*field, t| field.* = .{ | ||
| 4029 | .name = t.name ++ "", | ||
| 4030 | .type = *@field(Tag, t.name).Type(), | ||
| 4031 | .default_value = null, | ||
| 4032 | .is_comptime = false, | ||
| 4033 | .alignment = 0, | ||
| 4034 | }; | ||
| 4035 | break :map @Type(.{ .Struct = .{ | ||
| 4036 | .layout = .@"extern", | ||
| 4037 | .fields = &fields, | ||
| 4038 | .decls = &.{}, | ||
| 4039 | .is_tuple = false, | ||
| 4040 | } }); | ||
| 4041 | }) void { | ||
| 4042 | _ = self; | ||
| 4043 | _ = tag_to_payload_map; | ||
| 4044 | } | ||
| 4045 | |||
| 4046 | comptime { | ||
| 4047 | if (!builtin.strip_debug_info) { | ||
| 4048 | _ = &dbHelper; | ||
| 4049 | } | ||
| 4050 | } |
src/arch/aarch64/CodeGen.zig+4-8| ... | @@ -10,7 +10,6 @@ const Emit = @import("Emit.zig"); | ... | @@ -10,7 +10,6 @@ const Emit = @import("Emit.zig"); |
| 10 | const Liveness = @import("../../Liveness.zig"); | 10 | const Liveness = @import("../../Liveness.zig"); |
| 11 | const Type = @import("../../type.zig").Type; | 11 | const Type = @import("../../type.zig").Type; |
| 12 | const Value = @import("../../Value.zig"); | 12 | const Value = @import("../../Value.zig"); |
| 13 | const TypedValue = @import("../../TypedValue.zig"); | ||
| 14 | const link = @import("../../link.zig"); | 13 | const link = @import("../../link.zig"); |
| 15 | const Module = @import("../../Module.zig"); | 14 | const Module = @import("../../Module.zig"); |
| 16 | const InternPool = @import("../../InternPool.zig"); | 15 | const InternPool = @import("../../InternPool.zig"); |
| ... | @@ -342,7 +341,7 @@ pub fn generate( | ... | @@ -342,7 +341,7 @@ pub fn generate( |
| 342 | const func = zcu.funcInfo(func_index); | 341 | const func = zcu.funcInfo(func_index); |
| 343 | const fn_owner_decl = zcu.declPtr(func.owner_decl); | 342 | const fn_owner_decl = zcu.declPtr(func.owner_decl); |
| 344 | assert(fn_owner_decl.has_tv); | 343 | assert(fn_owner_decl.has_tv); |
| 345 | const fn_type = fn_owner_decl.ty; | 344 | const fn_type = fn_owner_decl.typeOf(zcu); |
| 346 | const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); | 345 | const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); |
| 347 | const target = &namespace.file_scope.mod.resolved_target.result; | 346 | const target = &namespace.file_scope.mod.resolved_target.result; |
| 348 | 347 | ||
| ... | @@ -6143,10 +6142,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -6143,10 +6142,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { |
| 6143 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod)) | 6142 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod)) |
| 6144 | return MCValue{ .none = {} }; | 6143 | return MCValue{ .none = {} }; |
| 6145 | 6144 | ||
| 6146 | const inst_index = inst.toIndex() orelse return self.genTypedValue(.{ | 6145 | const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, mod)).?); |
| 6147 | .ty = inst_ty, | ||
| 6148 | .val = (try self.air.value(inst, mod)).?, | ||
| 6149 | }); | ||
| 6150 | 6146 | ||
| 6151 | return self.getResolvedInstValue(inst_index); | 6147 | return self.getResolvedInstValue(inst_index); |
| 6152 | } | 6148 | } |
| ... | @@ -6163,11 +6159,11 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { | ... | @@ -6163,11 +6159,11 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { |
| 6163 | } | 6159 | } |
| 6164 | } | 6160 | } |
| 6165 | 6161 | ||
| 6166 | fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { | 6162 | fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { |
| 6167 | const mcv: MCValue = switch (try codegen.genTypedValue( | 6163 | const mcv: MCValue = switch (try codegen.genTypedValue( |
| 6168 | self.bin_file, | 6164 | self.bin_file, |
| 6169 | self.src_loc, | 6165 | self.src_loc, |
| 6170 | arg_tv, | 6166 | val, |
| 6171 | self.owner_decl, | 6167 | self.owner_decl, |
| 6172 | )) { | 6168 | )) { |
| 6173 | .mcv => |mcv| switch (mcv) { | 6169 | .mcv => |mcv| switch (mcv) { |
src/arch/arm/CodeGen.zig+4-8| ... | @@ -10,7 +10,6 @@ const Emit = @import("Emit.zig"); | ... | @@ -10,7 +10,6 @@ const Emit = @import("Emit.zig"); |
| 10 | const Liveness = @import("../../Liveness.zig"); | 10 | const Liveness = @import("../../Liveness.zig"); |
| 11 | const Type = @import("../../type.zig").Type; | 11 | const Type = @import("../../type.zig").Type; |
| 12 | const Value = @import("../../Value.zig"); | 12 | const Value = @import("../../Value.zig"); |
| 13 | const TypedValue = @import("../../TypedValue.zig"); | ||
| 14 | const link = @import("../../link.zig"); | 13 | const link = @import("../../link.zig"); |
| 15 | const Module = @import("../../Module.zig"); | 14 | const Module = @import("../../Module.zig"); |
| 16 | const InternPool = @import("../../InternPool.zig"); | 15 | const InternPool = @import("../../InternPool.zig"); |
| ... | @@ -349,7 +348,7 @@ pub fn generate( | ... | @@ -349,7 +348,7 @@ pub fn generate( |
| 349 | const func = zcu.funcInfo(func_index); | 348 | const func = zcu.funcInfo(func_index); |
| 350 | const fn_owner_decl = zcu.declPtr(func.owner_decl); | 349 | const fn_owner_decl = zcu.declPtr(func.owner_decl); |
| 351 | assert(fn_owner_decl.has_tv); | 350 | assert(fn_owner_decl.has_tv); |
| 352 | const fn_type = fn_owner_decl.ty; | 351 | const fn_type = fn_owner_decl.typeOf(zcu); |
| 353 | const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); | 352 | const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); |
| 354 | const target = &namespace.file_scope.mod.resolved_target.result; | 353 | const target = &namespace.file_scope.mod.resolved_target.result; |
| 355 | 354 | ||
| ... | @@ -6097,10 +6096,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -6097,10 +6096,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { |
| 6097 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod)) | 6096 | if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod)) |
| 6098 | return MCValue{ .none = {} }; | 6097 | return MCValue{ .none = {} }; |
| 6099 | 6098 | ||
| 6100 | const inst_index = inst.toIndex() orelse return self.genTypedValue(.{ | 6099 | const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, mod)).?); |
| 6101 | .ty = inst_ty, | ||
| 6102 | .val = (try self.air.value(inst, mod)).?, | ||
| 6103 | }); | ||
| 6104 | 6100 | ||
| 6105 | return self.getResolvedInstValue(inst_index); | 6101 | return self.getResolvedInstValue(inst_index); |
| 6106 | } | 6102 | } |
| ... | @@ -6117,12 +6113,12 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { | ... | @@ -6117,12 +6113,12 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { |
| 6117 | } | 6113 | } |
| 6118 | } | 6114 | } |
| 6119 | 6115 | ||
| 6120 | fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { | 6116 | fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { |
| 6121 | const mod = self.bin_file.comp.module.?; | 6117 | const mod = self.bin_file.comp.module.?; |
| 6122 | const mcv: MCValue = switch (try codegen.genTypedValue( | 6118 | const mcv: MCValue = switch (try codegen.genTypedValue( |
| 6123 | self.bin_file, | 6119 | self.bin_file, |
| 6124 | self.src_loc, | 6120 | self.src_loc, |
| 6125 | arg_tv, | 6121 | val, |
| 6126 | mod.funcOwnerDeclIndex(self.func_index), | 6122 | mod.funcOwnerDeclIndex(self.func_index), |
| 6127 | )) { | 6123 | )) { |
| 6128 | .mcv => |mcv| switch (mcv) { | 6124 | .mcv => |mcv| switch (mcv) { |
src/arch/riscv64/CodeGen.zig+4-8| ... | @@ -9,7 +9,6 @@ const Emit = @import("Emit.zig"); | ... | @@ -9,7 +9,6 @@ const Emit = @import("Emit.zig"); |
| 9 | const Liveness = @import("../../Liveness.zig"); | 9 | const Liveness = @import("../../Liveness.zig"); |
| 10 | const Type = @import("../../type.zig").Type; | 10 | const Type = @import("../../type.zig").Type; |
| 11 | const Value = @import("../../Value.zig"); | 11 | const Value = @import("../../Value.zig"); |
| 12 | const TypedValue = @import("../../TypedValue.zig"); | ||
| 13 | const link = @import("../../link.zig"); | 12 | const link = @import("../../link.zig"); |
| 14 | const Module = @import("../../Module.zig"); | 13 | const Module = @import("../../Module.zig"); |
| 15 | const InternPool = @import("../../InternPool.zig"); | 14 | const InternPool = @import("../../InternPool.zig"); |
| ... | @@ -230,7 +229,7 @@ pub fn generate( | ... | @@ -230,7 +229,7 @@ pub fn generate( |
| 230 | const func = zcu.funcInfo(func_index); | 229 | const func = zcu.funcInfo(func_index); |
| 231 | const fn_owner_decl = zcu.declPtr(func.owner_decl); | 230 | const fn_owner_decl = zcu.declPtr(func.owner_decl); |
| 232 | assert(fn_owner_decl.has_tv); | 231 | assert(fn_owner_decl.has_tv); |
| 233 | const fn_type = fn_owner_decl.ty; | 232 | const fn_type = fn_owner_decl.typeOf(zcu); |
| 234 | const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); | 233 | const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); |
| 235 | const target = &namespace.file_scope.mod.resolved_target.result; | 234 | const target = &namespace.file_scope.mod.resolved_target.result; |
| 236 | 235 | ||
| ... | @@ -2552,10 +2551,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -2552,10 +2551,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { |
| 2552 | if (!inst_ty.hasRuntimeBits(mod)) | 2551 | if (!inst_ty.hasRuntimeBits(mod)) |
| 2553 | return MCValue{ .none = {} }; | 2552 | return MCValue{ .none = {} }; |
| 2554 | 2553 | ||
| 2555 | const inst_index = inst.toIndex() orelse return self.genTypedValue(.{ | 2554 | const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, mod)).?); |
| 2556 | .ty = inst_ty, | ||
| 2557 | .val = (try self.air.value(inst, mod)).?, | ||
| 2558 | }); | ||
| 2559 | 2555 | ||
| 2560 | return self.getResolvedInstValue(inst_index); | 2556 | return self.getResolvedInstValue(inst_index); |
| 2561 | } | 2557 | } |
| ... | @@ -2572,12 +2568,12 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { | ... | @@ -2572,12 +2568,12 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { |
| 2572 | } | 2568 | } |
| 2573 | } | 2569 | } |
| 2574 | 2570 | ||
| 2575 | fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { | 2571 | fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { |
| 2576 | const mod = self.bin_file.comp.module.?; | 2572 | const mod = self.bin_file.comp.module.?; |
| 2577 | const mcv: MCValue = switch (try codegen.genTypedValue( | 2573 | const mcv: MCValue = switch (try codegen.genTypedValue( |
| 2578 | self.bin_file, | 2574 | self.bin_file, |
| 2579 | self.src_loc, | 2575 | self.src_loc, |
| 2580 | typed_value, | 2576 | val, |
| 2581 | mod.funcOwnerDeclIndex(self.func_index), | 2577 | mod.funcOwnerDeclIndex(self.func_index), |
| 2582 | )) { | 2578 | )) { |
| 2583 | .mcv => |mcv| switch (mcv) { | 2579 | .mcv => |mcv| switch (mcv) { |
src/arch/sparc64/CodeGen.zig+5-8| ... | @@ -12,7 +12,7 @@ const builtin = @import("builtin"); | ... | @@ -12,7 +12,7 @@ const builtin = @import("builtin"); |
| 12 | const link = @import("../../link.zig"); | 12 | const link = @import("../../link.zig"); |
| 13 | const Module = @import("../../Module.zig"); | 13 | const Module = @import("../../Module.zig"); |
| 14 | const InternPool = @import("../../InternPool.zig"); | 14 | const InternPool = @import("../../InternPool.zig"); |
| 15 | const TypedValue = @import("../../TypedValue.zig"); | 15 | const Value = @import("../../Value.zig"); |
| 16 | const ErrorMsg = Module.ErrorMsg; | 16 | const ErrorMsg = Module.ErrorMsg; |
| 17 | const codegen = @import("../../codegen.zig"); | 17 | const codegen = @import("../../codegen.zig"); |
| 18 | const Air = @import("../../Air.zig"); | 18 | const Air = @import("../../Air.zig"); |
| ... | @@ -273,7 +273,7 @@ pub fn generate( | ... | @@ -273,7 +273,7 @@ pub fn generate( |
| 273 | const func = zcu.funcInfo(func_index); | 273 | const func = zcu.funcInfo(func_index); |
| 274 | const fn_owner_decl = zcu.declPtr(func.owner_decl); | 274 | const fn_owner_decl = zcu.declPtr(func.owner_decl); |
| 275 | assert(fn_owner_decl.has_tv); | 275 | assert(fn_owner_decl.has_tv); |
| 276 | const fn_type = fn_owner_decl.ty; | 276 | const fn_type = fn_owner_decl.typeOf(zcu); |
| 277 | const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); | 277 | const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); |
| 278 | const target = &namespace.file_scope.mod.resolved_target.result; | 278 | const target = &namespace.file_scope.mod.resolved_target.result; |
| 279 | 279 | ||
| ... | @@ -4118,12 +4118,12 @@ fn genStoreASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Re | ... | @@ -4118,12 +4118,12 @@ fn genStoreASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Re |
| 4118 | } | 4118 | } |
| 4119 | } | 4119 | } |
| 4120 | 4120 | ||
| 4121 | fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { | 4121 | fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { |
| 4122 | const mod = self.bin_file.comp.module.?; | 4122 | const mod = self.bin_file.comp.module.?; |
| 4123 | const mcv: MCValue = switch (try codegen.genTypedValue( | 4123 | const mcv: MCValue = switch (try codegen.genTypedValue( |
| 4124 | self.bin_file, | 4124 | self.bin_file, |
| 4125 | self.src_loc, | 4125 | self.src_loc, |
| 4126 | typed_value, | 4126 | val, |
| 4127 | mod.funcOwnerDeclIndex(self.func_index), | 4127 | mod.funcOwnerDeclIndex(self.func_index), |
| 4128 | )) { | 4128 | )) { |
| 4129 | .mcv => |mcv| switch (mcv) { | 4129 | .mcv => |mcv| switch (mcv) { |
| ... | @@ -4546,10 +4546,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -4546,10 +4546,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { |
| 4546 | return self.getResolvedInstValue(inst); | 4546 | return self.getResolvedInstValue(inst); |
| 4547 | } | 4547 | } |
| 4548 | 4548 | ||
| 4549 | return self.genTypedValue(.{ | 4549 | return self.genTypedValue((try self.air.value(ref, mod)).?); |
| 4550 | .ty = ty, | ||
| 4551 | .val = (try self.air.value(ref, mod)).?, | ||
| 4552 | }); | ||
| 4553 | } | 4550 | } |
| 4554 | 4551 | ||
| 4555 | fn ret(self: *Self, mcv: MCValue) !void { | 4552 | fn ret(self: *Self, mcv: MCValue) !void { |
src/arch/wasm/CodeGen.zig+25-30| ... | @@ -18,7 +18,6 @@ const Value = @import("../../Value.zig"); | ... | @@ -18,7 +18,6 @@ const Value = @import("../../Value.zig"); |
| 18 | const Compilation = @import("../../Compilation.zig"); | 18 | const Compilation = @import("../../Compilation.zig"); |
| 19 | const LazySrcLoc = std.zig.LazySrcLoc; | 19 | const LazySrcLoc = std.zig.LazySrcLoc; |
| 20 | const link = @import("../../link.zig"); | 20 | const link = @import("../../link.zig"); |
| 21 | const TypedValue = @import("../../TypedValue.zig"); | ||
| 22 | const Air = @import("../../Air.zig"); | 21 | const Air = @import("../../Air.zig"); |
| 23 | const Liveness = @import("../../Liveness.zig"); | 22 | const Liveness = @import("../../Liveness.zig"); |
| 24 | const target_util = @import("../../target.zig"); | 23 | const target_util = @import("../../target.zig"); |
| ... | @@ -805,7 +804,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue { | ... | @@ -805,7 +804,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue { |
| 805 | // In the other cases, we will simply lower the constant to a value that fits | 804 | // In the other cases, we will simply lower the constant to a value that fits |
| 806 | // into a single local (such as a pointer, integer, bool, etc). | 805 | // into a single local (such as a pointer, integer, bool, etc). |
| 807 | const result = if (isByRef(ty, mod)) blk: { | 806 | const result = if (isByRef(ty, mod)) blk: { |
| 808 | const sym_index = try func.bin_file.lowerUnnamedConst(.{ .ty = ty, .val = val }, func.decl_index); | 807 | const sym_index = try func.bin_file.lowerUnnamedConst(val, func.decl_index); |
| 809 | break :blk WValue{ .memory = sym_index }; | 808 | break :blk WValue{ .memory = sym_index }; |
| 810 | } else try func.lowerConstant(val, ty); | 809 | } else try func.lowerConstant(val, ty); |
| 811 | 810 | ||
| ... | @@ -1243,12 +1242,12 @@ pub fn generate( | ... | @@ -1243,12 +1242,12 @@ pub fn generate( |
| 1243 | fn genFunc(func: *CodeGen) InnerError!void { | 1242 | fn genFunc(func: *CodeGen) InnerError!void { |
| 1244 | const mod = func.bin_file.base.comp.module.?; | 1243 | const mod = func.bin_file.base.comp.module.?; |
| 1245 | const ip = &mod.intern_pool; | 1244 | const ip = &mod.intern_pool; |
| 1246 | const fn_info = mod.typeToFunc(func.decl.ty).?; | 1245 | const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?; |
| 1247 | var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), mod); | 1246 | var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), mod); |
| 1248 | defer func_type.deinit(func.gpa); | 1247 | defer func_type.deinit(func.gpa); |
| 1249 | _ = try func.bin_file.storeDeclType(func.decl_index, func_type); | 1248 | _ = try func.bin_file.storeDeclType(func.decl_index, func_type); |
| 1250 | 1249 | ||
| 1251 | var cc_result = try func.resolveCallingConventionValues(func.decl.ty); | 1250 | var cc_result = try func.resolveCallingConventionValues(func.decl.typeOf(mod)); |
| 1252 | defer cc_result.deinit(func.gpa); | 1251 | defer cc_result.deinit(func.gpa); |
| 1253 | 1252 | ||
| 1254 | func.args = cc_result.args; | 1253 | func.args = cc_result.args; |
| ... | @@ -2087,7 +2086,7 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2087,7 +2086,7 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2087 | const mod = func.bin_file.base.comp.module.?; | 2086 | const mod = func.bin_file.base.comp.module.?; |
| 2088 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 2087 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 2089 | const operand = try func.resolveInst(un_op); | 2088 | const operand = try func.resolveInst(un_op); |
| 2090 | const fn_info = mod.typeToFunc(func.decl.ty).?; | 2089 | const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?; |
| 2091 | const ret_ty = Type.fromInterned(fn_info.return_type); | 2090 | const ret_ty = Type.fromInterned(fn_info.return_type); |
| 2092 | 2091 | ||
| 2093 | // result must be stored in the stack and we return a pointer | 2092 | // result must be stored in the stack and we return a pointer |
| ... | @@ -2135,7 +2134,7 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2135,7 +2134,7 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2135 | break :result try func.allocStack(Type.usize); // create pointer to void | 2134 | break :result try func.allocStack(Type.usize); // create pointer to void |
| 2136 | } | 2135 | } |
| 2137 | 2136 | ||
| 2138 | const fn_info = mod.typeToFunc(func.decl.ty).?; | 2137 | const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?; |
| 2139 | if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), mod)) { | 2138 | if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), mod)) { |
| 2140 | break :result func.return_value; | 2139 | break :result func.return_value; |
| 2141 | } | 2140 | } |
| ... | @@ -2152,7 +2151,7 @@ fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2152,7 +2151,7 @@ fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2152 | const operand = try func.resolveInst(un_op); | 2151 | const operand = try func.resolveInst(un_op); |
| 2153 | const ret_ty = func.typeOf(un_op).childType(mod); | 2152 | const ret_ty = func.typeOf(un_op).childType(mod); |
| 2154 | 2153 | ||
| 2155 | const fn_info = mod.typeToFunc(func.decl.ty).?; | 2154 | const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?; |
| 2156 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 2155 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 2157 | if (ret_ty.isError(mod)) { | 2156 | if (ret_ty.isError(mod)) { |
| 2158 | try func.addImm32(0); | 2157 | try func.addImm32(0); |
| ... | @@ -2193,7 +2192,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif | ... | @@ -2193,7 +2192,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2193 | break :blk function.owner_decl; | 2192 | break :blk function.owner_decl; |
| 2194 | } else if (func_val.getExternFunc(mod)) |extern_func| { | 2193 | } else if (func_val.getExternFunc(mod)) |extern_func| { |
| 2195 | const ext_decl = mod.declPtr(extern_func.decl); | 2194 | const ext_decl = mod.declPtr(extern_func.decl); |
| 2196 | const ext_info = mod.typeToFunc(ext_decl.ty).?; | 2195 | const ext_info = mod.typeToFunc(ext_decl.typeOf(mod)).?; |
| 2197 | var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types.get(ip), Type.fromInterned(ext_info.return_type), mod); | 2196 | var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types.get(ip), Type.fromInterned(ext_info.return_type), mod); |
| 2198 | defer func_type.deinit(func.gpa); | 2197 | defer func_type.deinit(func.gpa); |
| 2199 | const atom_index = try func.bin_file.getOrCreateAtomForDecl(extern_func.decl); | 2198 | const atom_index = try func.bin_file.getOrCreateAtomForDecl(extern_func.decl); |
| ... | @@ -2216,7 +2215,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif | ... | @@ -2216,7 +2215,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2216 | }, | 2215 | }, |
| 2217 | else => {}, | 2216 | else => {}, |
| 2218 | } | 2217 | } |
| 2219 | return func.fail("Expected a function, but instead found type '{}'", .{func_val.tag()}); | 2218 | return func.fail("Expected a function, but instead found '{s}'", .{@tagName(ip.indexToKey(func_val.toIntern()))}); |
| 2220 | }; | 2219 | }; |
| 2221 | 2220 | ||
| 2222 | const sret = if (first_param_sret) blk: { | 2221 | const sret = if (first_param_sret) blk: { |
| ... | @@ -2530,7 +2529,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2530,7 +2529,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2530 | const mod = func.bin_file.base.comp.module.?; | 2529 | const mod = func.bin_file.base.comp.module.?; |
| 2531 | const arg_index = func.arg_index; | 2530 | const arg_index = func.arg_index; |
| 2532 | const arg = func.args[arg_index]; | 2531 | const arg = func.args[arg_index]; |
| 2533 | const cc = mod.typeToFunc(func.decl.ty).?.cc; | 2532 | const cc = mod.typeToFunc(func.decl.typeOf(mod)).?.cc; |
| 2534 | const arg_ty = func.typeOfIndex(inst); | 2533 | const arg_ty = func.typeOfIndex(inst); |
| 2535 | if (cc == .C) { | 2534 | if (cc == .C) { |
| 2536 | const arg_classes = abi.classifyType(arg_ty, mod); | 2535 | const arg_classes = abi.classifyType(arg_ty, mod); |
| ... | @@ -3119,11 +3118,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue | ... | @@ -3119,11 +3118,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue |
| 3119 | } | 3118 | } |
| 3120 | 3119 | ||
| 3121 | fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue { | 3120 | fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue { |
| 3122 | const mod = func.bin_file.base.comp.module.?; | 3121 | return func.lowerDeclRefValue(ptr_val, decl_index, offset); |
| 3123 | const decl = mod.declPtr(decl_index); | ||
| 3124 | try mod.markDeclAlive(decl); | ||
| 3125 | const ptr_ty = try mod.singleMutPtrType(decl.ty); | ||
| 3126 | return func.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index, offset); | ||
| 3127 | } | 3122 | } |
| 3128 | 3123 | ||
| 3129 | fn lowerAnonDeclRef( | 3124 | fn lowerAnonDeclRef( |
| ... | @@ -3158,7 +3153,7 @@ fn lowerAnonDeclRef( | ... | @@ -3158,7 +3153,7 @@ fn lowerAnonDeclRef( |
| 3158 | } else return WValue{ .memory_offset = .{ .pointer = target_sym_index, .offset = offset } }; | 3153 | } else return WValue{ .memory_offset = .{ .pointer = target_sym_index, .offset = offset } }; |
| 3159 | } | 3154 | } |
| 3160 | 3155 | ||
| 3161 | fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue { | 3156 | fn lowerDeclRefValue(func: *CodeGen, val: Value, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue { |
| 3162 | const mod = func.bin_file.base.comp.module.?; | 3157 | const mod = func.bin_file.base.comp.module.?; |
| 3163 | 3158 | ||
| 3164 | const decl = mod.declPtr(decl_index); | 3159 | const decl = mod.declPtr(decl_index); |
| ... | @@ -3166,23 +3161,23 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: InternPool.Decl | ... | @@ -3166,23 +3161,23 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: InternPool.Decl |
| 3166 | // want to lower the actual decl, rather than the alias itself. | 3161 | // want to lower the actual decl, rather than the alias itself. |
| 3167 | if (decl.val.getFunction(mod)) |func_val| { | 3162 | if (decl.val.getFunction(mod)) |func_val| { |
| 3168 | if (func_val.owner_decl != decl_index) { | 3163 | if (func_val.owner_decl != decl_index) { |
| 3169 | return func.lowerDeclRefValue(tv, func_val.owner_decl, offset); | 3164 | return func.lowerDeclRefValue(val, func_val.owner_decl, offset); |
| 3170 | } | 3165 | } |
| 3171 | } else if (decl.val.getExternFunc(mod)) |func_val| { | 3166 | } else if (decl.val.getExternFunc(mod)) |func_val| { |
| 3172 | if (func_val.decl != decl_index) { | 3167 | if (func_val.decl != decl_index) { |
| 3173 | return func.lowerDeclRefValue(tv, func_val.decl, offset); | 3168 | return func.lowerDeclRefValue(val, func_val.decl, offset); |
| 3174 | } | 3169 | } |
| 3175 | } | 3170 | } |
| 3176 | if (decl.ty.zigTypeTag(mod) != .Fn and !decl.ty.hasRuntimeBitsIgnoreComptime(mod)) { | 3171 | const decl_ty = decl.typeOf(mod); |
| 3172 | if (decl_ty.zigTypeTag(mod) != .Fn and !decl_ty.hasRuntimeBitsIgnoreComptime(mod)) { | ||
| 3177 | return WValue{ .imm32 = 0xaaaaaaaa }; | 3173 | return WValue{ .imm32 = 0xaaaaaaaa }; |
| 3178 | } | 3174 | } |
| 3179 | 3175 | ||
| 3180 | try mod.markDeclAlive(decl); | ||
| 3181 | const atom_index = try func.bin_file.getOrCreateAtomForDecl(decl_index); | 3176 | const atom_index = try func.bin_file.getOrCreateAtomForDecl(decl_index); |
| 3182 | const atom = func.bin_file.getAtom(atom_index); | 3177 | const atom = func.bin_file.getAtom(atom_index); |
| 3183 | 3178 | ||
| 3184 | const target_sym_index = @intFromEnum(atom.sym_index); | 3179 | const target_sym_index = @intFromEnum(atom.sym_index); |
| 3185 | if (decl.ty.zigTypeTag(mod) == .Fn) { | 3180 | if (decl_ty.zigTypeTag(mod) == .Fn) { |
| 3186 | return WValue{ .function_index = target_sym_index }; | 3181 | return WValue{ .function_index = target_sym_index }; |
| 3187 | } else if (offset == 0) { | 3182 | } else if (offset == 0) { |
| 3188 | return WValue{ .memory = target_sym_index }; | 3183 | return WValue{ .memory = target_sym_index }; |
| ... | @@ -3281,23 +3276,23 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { | ... | @@ -3281,23 +3276,23 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3281 | }, | 3276 | }, |
| 3282 | .error_union => |error_union| { | 3277 | .error_union => |error_union| { |
| 3283 | const err_int_ty = try mod.errorIntType(); | 3278 | const err_int_ty = try mod.errorIntType(); |
| 3284 | const err_tv: TypedValue = switch (error_union.val) { | 3279 | const err_ty, const err_val = switch (error_union.val) { |
| 3285 | .err_name => |err_name| .{ | 3280 | .err_name => |err_name| .{ |
| 3286 | .ty = ty.errorUnionSet(mod), | 3281 | ty.errorUnionSet(mod), |
| 3287 | .val = Value.fromInterned((try mod.intern(.{ .err = .{ | 3282 | Value.fromInterned((try mod.intern(.{ .err = .{ |
| 3288 | .ty = ty.errorUnionSet(mod).toIntern(), | 3283 | .ty = ty.errorUnionSet(mod).toIntern(), |
| 3289 | .name = err_name, | 3284 | .name = err_name, |
| 3290 | } }))), | 3285 | } }))), |
| 3291 | }, | 3286 | }, |
| 3292 | .payload => .{ | 3287 | .payload => .{ |
| 3293 | .ty = err_int_ty, | 3288 | err_int_ty, |
| 3294 | .val = try mod.intValue(err_int_ty, 0), | 3289 | try mod.intValue(err_int_ty, 0), |
| 3295 | }, | 3290 | }, |
| 3296 | }; | 3291 | }; |
| 3297 | const payload_type = ty.errorUnionPayload(mod); | 3292 | const payload_type = ty.errorUnionPayload(mod); |
| 3298 | if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) { | 3293 | if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) { |
| 3299 | // We use the error type directly as the type. | 3294 | // We use the error type directly as the type. |
| 3300 | return func.lowerConstant(err_tv.val, err_tv.ty); | 3295 | return func.lowerConstant(err_val, err_ty); |
| 3301 | } | 3296 | } |
| 3302 | 3297 | ||
| 3303 | return func.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{}); | 3298 | return func.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{}); |
| ... | @@ -3321,10 +3316,10 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { | ... | @@ -3321,10 +3316,10 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3321 | .elem, .field => |base_index| ptr = ip.indexToKey(base_index.base).ptr, | 3316 | .elem, .field => |base_index| ptr = ip.indexToKey(base_index.base).ptr, |
| 3322 | .comptime_field, .comptime_alloc => unreachable, | 3317 | .comptime_field, .comptime_alloc => unreachable, |
| 3323 | }; | 3318 | }; |
| 3324 | return .{ .memory = try func.bin_file.lowerUnnamedConst(.{ .ty = ty, .val = val }, owner_decl) }; | 3319 | return .{ .memory = try func.bin_file.lowerUnnamedConst(val, owner_decl) }; |
| 3325 | }, | 3320 | }, |
| 3326 | .ptr => |ptr| switch (ptr.addr) { | 3321 | .ptr => |ptr| switch (ptr.addr) { |
| 3327 | .decl => |decl| return func.lowerDeclRefValue(.{ .ty = ty, .val = val }, decl, 0), | 3322 | .decl => |decl| return func.lowerDeclRefValue(val, decl, 0), |
| 3328 | .int => |int| return func.lowerConstant(Value.fromInterned(int), Type.fromInterned(ip.typeOf(int))), | 3323 | .int => |int| return func.lowerConstant(Value.fromInterned(int), Type.fromInterned(ip.typeOf(int))), |
| 3329 | .opt_payload, .elem, .field => return func.lowerParentPtr(val, 0), | 3324 | .opt_payload, .elem, .field => return func.lowerParentPtr(val, 0), |
| 3330 | .anon_decl => |ad| return func.lowerAnonDeclRef(ad, 0), | 3325 | .anon_decl => |ad| return func.lowerAnonDeclRef(ad, 0), |
| ... | @@ -7286,7 +7281,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { | ... | @@ -7286,7 +7281,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { |
| 7286 | .storage = .{ .bytes = tag_name }, | 7281 | .storage = .{ .bytes = tag_name }, |
| 7287 | } }); | 7282 | } }); |
| 7288 | const tag_sym_index = try func.bin_file.lowerUnnamedConst( | 7283 | const tag_sym_index = try func.bin_file.lowerUnnamedConst( |
| 7289 | .{ .ty = name_ty, .val = Value.fromInterned(name_val) }, | 7284 | Value.fromInterned(name_val), |
| 7290 | enum_decl_index, | 7285 | enum_decl_index, |
| 7291 | ); | 7286 | ); |
| 7292 | 7287 |
src/arch/x86_64/CodeGen.zig+42-72| ... | @@ -32,7 +32,6 @@ const InternPool = @import("../../InternPool.zig"); | ... | @@ -32,7 +32,6 @@ const InternPool = @import("../../InternPool.zig"); |
| 32 | const Alignment = InternPool.Alignment; | 32 | const Alignment = InternPool.Alignment; |
| 33 | const Target = std.Target; | 33 | const Target = std.Target; |
| 34 | const Type = @import("../../type.zig").Type; | 34 | const Type = @import("../../type.zig").Type; |
| 35 | const TypedValue = @import("../../TypedValue.zig"); | ||
| 36 | const Value = @import("../../Value.zig"); | 35 | const Value = @import("../../Value.zig"); |
| 37 | const Instruction = @import("encoder.zig").Instruction; | 36 | const Instruction = @import("encoder.zig").Instruction; |
| 38 | 37 | ||
| ... | @@ -808,7 +807,7 @@ pub fn generate( | ... | @@ -808,7 +807,7 @@ pub fn generate( |
| 808 | const func = zcu.funcInfo(func_index); | 807 | const func = zcu.funcInfo(func_index); |
| 809 | const fn_owner_decl = zcu.declPtr(func.owner_decl); | 808 | const fn_owner_decl = zcu.declPtr(func.owner_decl); |
| 810 | assert(fn_owner_decl.has_tv); | 809 | assert(fn_owner_decl.has_tv); |
| 811 | const fn_type = fn_owner_decl.ty; | 810 | const fn_type = fn_owner_decl.typeOf(zcu); |
| 812 | const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); | 811 | const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); |
| 813 | const mod = namespace.file_scope.mod; | 812 | const mod = namespace.file_scope.mod; |
| 814 | 813 | ||
| ... | @@ -2250,7 +2249,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { | ... | @@ -2250,7 +2249,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 2250 | for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, tag_index| { | 2249 | for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, tag_index| { |
| 2251 | const tag_name_len = ip.stringToSlice(tag_names.get(ip)[tag_index]).len; | 2250 | const tag_name_len = ip.stringToSlice(tag_names.get(ip)[tag_index]).len; |
| 2252 | const tag_val = try mod.enumValueFieldIndex(enum_ty, @intCast(tag_index)); | 2251 | const tag_val = try mod.enumValueFieldIndex(enum_ty, @intCast(tag_index)); |
| 2253 | const tag_mcv = try self.genTypedValue(.{ .ty = enum_ty, .val = tag_val }); | 2252 | const tag_mcv = try self.genTypedValue(tag_val); |
| 2254 | try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv); | 2253 | try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv); |
| 2255 | const skip_reloc = try self.asmJccReloc(.ne, undefined); | 2254 | const skip_reloc = try self.asmJccReloc(.ne, undefined); |
| 2256 | 2255 | ||
| ... | @@ -3323,7 +3322,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3323,7 +3322,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 3323 | .storage = .{ .repeated_elem = mask_val.ip_index }, | 3322 | .storage = .{ .repeated_elem = mask_val.ip_index }, |
| 3324 | } }); | 3323 | } }); |
| 3325 | 3324 | ||
| 3326 | const splat_mcv = try self.genTypedValue(.{ .ty = splat_ty, .val = Value.fromInterned(splat_val) }); | 3325 | const splat_mcv = try self.genTypedValue(Value.fromInterned(splat_val)); |
| 3327 | const splat_addr_mcv: MCValue = switch (splat_mcv) { | 3326 | const splat_addr_mcv: MCValue = switch (splat_mcv) { |
| 3328 | .memory, .indirect, .load_frame => splat_mcv.address(), | 3327 | .memory, .indirect, .load_frame => splat_mcv.address(), |
| 3329 | else => .{ .register = try self.copyToTmpRegister(Type.usize, splat_mcv.address()) }, | 3328 | else => .{ .register = try self.copyToTmpRegister(Type.usize, splat_mcv.address()) }, |
| ... | @@ -4992,17 +4991,14 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4992,17 +4991,14 @@ fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 4992 | defer self.register_manager.unlockReg(shift_lock); | 4991 | defer self.register_manager.unlockReg(shift_lock); |
| 4993 | 4992 | ||
| 4994 | const mask_ty = try mod.vectorType(.{ .len = 16, .child = .u8_type }); | 4993 | const mask_ty = try mod.vectorType(.{ .len = 16, .child = .u8_type }); |
| 4995 | const mask_mcv = try self.genTypedValue(.{ | 4994 | const mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{ |
| 4996 | .ty = mask_ty, | 4995 | .ty = mask_ty.toIntern(), |
| 4997 | .val = Value.fromInterned((try mod.intern(.{ .aggregate = .{ | 4996 | .storage = .{ .elems = &([1]InternPool.Index{ |
| 4998 | .ty = mask_ty.toIntern(), | 4997 | (try rhs_ty.childType(mod).maxIntScalar(mod, Type.u8)).toIntern(), |
| 4999 | .storage = .{ .elems = &([1]InternPool.Index{ | 4998 | } ++ [1]InternPool.Index{ |
| 5000 | (try rhs_ty.childType(mod).maxIntScalar(mod, Type.u8)).toIntern(), | 4999 | (try mod.intValue(Type.u8, 0)).toIntern(), |
| 5001 | } ++ [1]InternPool.Index{ | 5000 | } ** 15) }, |
| 5002 | (try mod.intValue(Type.u8, 0)).toIntern(), | 5001 | } }))); |
| 5003 | } ** 15) }, | ||
| 5004 | } }))), | ||
| 5005 | }); | ||
| 5006 | const mask_addr_reg = | 5002 | const mask_addr_reg = |
| 5007 | try self.copyToTmpRegister(Type.usize, mask_mcv.address()); | 5003 | try self.copyToTmpRegister(Type.usize, mask_mcv.address()); |
| 5008 | const mask_addr_lock = self.register_manager.lockRegAssumeUnused(mask_addr_reg); | 5004 | const mask_addr_lock = self.register_manager.lockRegAssumeUnused(mask_addr_reg); |
| ... | @@ -6860,11 +6856,11 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) | ... | @@ -6860,11 +6856,11 @@ fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) |
| 6860 | .child = (try mod.intType(.signed, scalar_bits)).ip_index, | 6856 | .child = (try mod.intType(.signed, scalar_bits)).ip_index, |
| 6861 | }); | 6857 | }); |
| 6862 | 6858 | ||
| 6863 | const sign_mcv = try self.genTypedValue(.{ .ty = vec_ty, .val = switch (tag) { | 6859 | const sign_mcv = try self.genTypedValue(switch (tag) { |
| 6864 | .neg => try vec_ty.minInt(mod, vec_ty), | 6860 | .neg => try vec_ty.minInt(mod, vec_ty), |
| 6865 | .abs => try vec_ty.maxInt(mod, vec_ty), | 6861 | .abs => try vec_ty.maxInt(mod, vec_ty), |
| 6866 | else => unreachable, | 6862 | else => unreachable, |
| 6867 | } }); | 6863 | }); |
| 6868 | const sign_mem: Memory = if (sign_mcv.isMemory()) | 6864 | const sign_mem: Memory = if (sign_mcv.isMemory()) |
| 6869 | try sign_mcv.mem(self, Memory.Size.fromSize(abi_size)) | 6865 | try sign_mcv.mem(self, Memory.Size.fromSize(abi_size)) |
| 6870 | else | 6866 | else |
| ... | @@ -11130,10 +11126,7 @@ fn genBinOp( | ... | @@ -11130,10 +11126,7 @@ fn genBinOp( |
| 11130 | .cmp_neq, | 11126 | .cmp_neq, |
| 11131 | => { | 11127 | => { |
| 11132 | const unsigned_ty = try lhs_ty.toUnsigned(mod); | 11128 | const unsigned_ty = try lhs_ty.toUnsigned(mod); |
| 11133 | const not_mcv = try self.genTypedValue(.{ | 11129 | const not_mcv = try self.genTypedValue(try unsigned_ty.maxInt(mod, unsigned_ty)); |
| 11134 | .ty = lhs_ty, | ||
| 11135 | .val = try unsigned_ty.maxInt(mod, unsigned_ty), | ||
| 11136 | }); | ||
| 11137 | const not_mem: Memory = if (not_mcv.isMemory()) | 11130 | const not_mem: Memory = if (not_mcv.isMemory()) |
| 11138 | try not_mcv.mem(self, Memory.Size.fromSize(abi_size)) | 11131 | try not_mcv.mem(self, Memory.Size.fromSize(abi_size)) |
| 11139 | else | 11132 | else |
| ... | @@ -12258,12 +12251,11 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12258,12 +12251,11 @@ fn genCall(self: *Self, info: union(enum) { |
| 12258 | switch (switch (func_key) { | 12251 | switch (switch (func_key) { |
| 12259 | else => func_key, | 12252 | else => func_key, |
| 12260 | .ptr => |ptr| switch (ptr.addr) { | 12253 | .ptr => |ptr| switch (ptr.addr) { |
| 12261 | .decl => |decl| mod.intern_pool.indexToKey(try mod.declPtr(decl).internValue(mod)), | 12254 | .decl => |decl| mod.intern_pool.indexToKey(mod.declPtr(decl).val.toIntern()), |
| 12262 | else => func_key, | 12255 | else => func_key, |
| 12263 | }, | 12256 | }, |
| 12264 | }) { | 12257 | }) { |
| 12265 | .func => |func| { | 12258 | .func => |func| { |
| 12266 | try mod.markDeclAlive(mod.declPtr(func.owner_decl)); | ||
| 12267 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { | 12259 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| 12268 | const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl); | 12260 | const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl); |
| 12269 | const sym = elf_file.symbol(sym_index); | 12261 | const sym = elf_file.symbol(sym_index); |
| ... | @@ -12323,7 +12315,6 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12323,7 +12315,6 @@ fn genCall(self: *Self, info: union(enum) { |
| 12323 | }, | 12315 | }, |
| 12324 | .extern_func => |extern_func| { | 12316 | .extern_func => |extern_func| { |
| 12325 | const owner_decl = mod.declPtr(extern_func.decl); | 12317 | const owner_decl = mod.declPtr(extern_func.decl); |
| 12326 | try mod.markDeclAlive(owner_decl); | ||
| 12327 | const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name); | 12318 | const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name); |
| 12328 | const decl_name = mod.intern_pool.stringToSlice(owner_decl.name); | 12319 | const decl_name = mod.intern_pool.stringToSlice(owner_decl.name); |
| 12329 | try self.genExternSymbolRef(.call, lib_name, decl_name); | 12320 | try self.genExternSymbolRef(.call, lib_name, decl_name); |
| ... | @@ -14694,10 +14685,7 @@ fn genSetReg( | ... | @@ -14694,10 +14685,7 @@ fn genSetReg( |
| 14694 | ), | 14685 | ), |
| 14695 | else => unreachable, | 14686 | else => unreachable, |
| 14696 | }, | 14687 | }, |
| 14697 | .segment, .x87, .mmx, .sse => try self.genSetReg(dst_reg, ty, try self.genTypedValue(.{ | 14688 | .segment, .x87, .mmx, .sse => try self.genSetReg(dst_reg, ty, try self.genTypedValue(try mod.undefValue(ty)), opts), |
| 14698 | .ty = ty, | ||
| 14699 | .val = try mod.undefValue(ty), | ||
| 14700 | }), opts), | ||
| 14701 | }, | 14689 | }, |
| 14702 | .eflags => |cc| try self.asmSetccRegister(cc, dst_reg.to8()), | 14690 | .eflags => |cc| try self.asmSetccRegister(cc, dst_reg.to8()), |
| 14703 | .immediate => |imm| { | 14691 | .immediate => |imm| { |
| ... | @@ -16895,13 +16883,10 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16895,13 +16883,10 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 16895 | .ty = mask_elem_ty.toIntern(), | 16883 | .ty = mask_elem_ty.toIntern(), |
| 16896 | .storage = .{ .u64 = bit / elem_bits }, | 16884 | .storage = .{ .u64 = bit / elem_bits }, |
| 16897 | } }); | 16885 | } }); |
| 16898 | const mask_mcv = try self.genTypedValue(.{ | 16886 | const mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{ |
| 16899 | .ty = mask_ty, | 16887 | .ty = mask_ty.toIntern(), |
| 16900 | .val = Value.fromInterned(try mod.intern(.{ .aggregate = .{ | 16888 | .storage = .{ .elems = mask_elems[0..vec_len] }, |
| 16901 | .ty = mask_ty.toIntern(), | 16889 | } }))); |
| 16902 | .storage = .{ .elems = mask_elems[0..vec_len] }, | ||
| 16903 | } })), | ||
| 16904 | }); | ||
| 16905 | const mask_mem: Memory = .{ | 16890 | const mask_mem: Memory = .{ |
| 16906 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, mask_mcv.address()) }, | 16891 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, mask_mcv.address()) }, |
| 16907 | .mod = .{ .rm = .{ .size = self.memSize(ty) } }, | 16892 | .mod = .{ .rm = .{ .size = self.memSize(ty) } }, |
| ... | @@ -16923,13 +16908,10 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16923,13 +16908,10 @@ fn airSelect(self: *Self, inst: Air.Inst.Index) !void { |
| 16923 | .ty = mask_elem_ty.toIntern(), | 16908 | .ty = mask_elem_ty.toIntern(), |
| 16924 | .storage = .{ .u64 = @as(u32, 1) << @intCast(bit & (elem_bits - 1)) }, | 16909 | .storage = .{ .u64 = @as(u32, 1) << @intCast(bit & (elem_bits - 1)) }, |
| 16925 | } }); | 16910 | } }); |
| 16926 | const mask_mcv = try self.genTypedValue(.{ | 16911 | const mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{ |
| 16927 | .ty = mask_ty, | 16912 | .ty = mask_ty.toIntern(), |
| 16928 | .val = Value.fromInterned(try mod.intern(.{ .aggregate = .{ | 16913 | .storage = .{ .elems = mask_elems[0..vec_len] }, |
| 16929 | .ty = mask_ty.toIntern(), | 16914 | } }))); |
| 16930 | .storage = .{ .elems = mask_elems[0..vec_len] }, | ||
| 16931 | } })), | ||
| 16932 | }); | ||
| 16933 | const mask_mem: Memory = .{ | 16915 | const mask_mem: Memory = .{ |
| 16934 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, mask_mcv.address()) }, | 16916 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, mask_mcv.address()) }, |
| 16935 | .mod = .{ .rm = .{ .size = self.memSize(ty) } }, | 16917 | .mod = .{ .rm = .{ .size = self.memSize(ty) } }, |
| ... | @@ -17660,13 +17642,10 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17660,13 +17642,10 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17660 | else | 17642 | else |
| 17661 | try select_mask_elem_ty.minIntScalar(mod, select_mask_elem_ty)).toIntern(); | 17643 | try select_mask_elem_ty.minIntScalar(mod, select_mask_elem_ty)).toIntern(); |
| 17662 | } | 17644 | } |
| 17663 | const select_mask_mcv = try self.genTypedValue(.{ | 17645 | const select_mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{ |
| 17664 | .ty = select_mask_ty, | 17646 | .ty = select_mask_ty.toIntern(), |
| 17665 | .val = Value.fromInterned(try mod.intern(.{ .aggregate = .{ | 17647 | .storage = .{ .elems = select_mask_elems[0..mask_elems.len] }, |
| 17666 | .ty = select_mask_ty.toIntern(), | 17648 | } }))); |
| 17667 | .storage = .{ .elems = select_mask_elems[0..mask_elems.len] }, | ||
| 17668 | } })), | ||
| 17669 | }); | ||
| 17670 | 17649 | ||
| 17671 | if (self.hasFeature(.sse4_1)) { | 17650 | if (self.hasFeature(.sse4_1)) { |
| 17672 | const mir_tag: Mir.Inst.FixedTag = .{ | 17651 | const mir_tag: Mir.Inst.FixedTag = .{ |
| ... | @@ -17811,13 +17790,10 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17811,13 +17790,10 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17811 | } }); | 17790 | } }); |
| 17812 | } | 17791 | } |
| 17813 | const lhs_mask_ty = try mod.vectorType(.{ .len = max_abi_size, .child = .u8_type }); | 17792 | const lhs_mask_ty = try mod.vectorType(.{ .len = max_abi_size, .child = .u8_type }); |
| 17814 | const lhs_mask_mcv = try self.genTypedValue(.{ | 17793 | const lhs_mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{ |
| 17815 | .ty = lhs_mask_ty, | 17794 | .ty = lhs_mask_ty.toIntern(), |
| 17816 | .val = Value.fromInterned(try mod.intern(.{ .aggregate = .{ | 17795 | .storage = .{ .elems = lhs_mask_elems[0..max_abi_size] }, |
| 17817 | .ty = lhs_mask_ty.toIntern(), | 17796 | } }))); |
| 17818 | .storage = .{ .elems = lhs_mask_elems[0..max_abi_size] }, | ||
| 17819 | } })), | ||
| 17820 | }); | ||
| 17821 | const lhs_mask_mem: Memory = .{ | 17797 | const lhs_mask_mem: Memory = .{ |
| 17822 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, lhs_mask_mcv.address()) }, | 17798 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, lhs_mask_mcv.address()) }, |
| 17823 | .mod = .{ .rm = .{ .size = Memory.Size.fromSize(@max(max_abi_size, 16)) } }, | 17799 | .mod = .{ .rm = .{ .size = Memory.Size.fromSize(@max(max_abi_size, 16)) } }, |
| ... | @@ -17848,13 +17824,10 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17848,13 +17824,10 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17848 | } }); | 17824 | } }); |
| 17849 | } | 17825 | } |
| 17850 | const rhs_mask_ty = try mod.vectorType(.{ .len = max_abi_size, .child = .u8_type }); | 17826 | const rhs_mask_ty = try mod.vectorType(.{ .len = max_abi_size, .child = .u8_type }); |
| 17851 | const rhs_mask_mcv = try self.genTypedValue(.{ | 17827 | const rhs_mask_mcv = try self.genTypedValue(Value.fromInterned(try mod.intern(.{ .aggregate = .{ |
| 17852 | .ty = rhs_mask_ty, | 17828 | .ty = rhs_mask_ty.toIntern(), |
| 17853 | .val = Value.fromInterned(try mod.intern(.{ .aggregate = .{ | 17829 | .storage = .{ .elems = rhs_mask_elems[0..max_abi_size] }, |
| 17854 | .ty = rhs_mask_ty.toIntern(), | 17830 | } }))); |
| 17855 | .storage = .{ .elems = rhs_mask_elems[0..max_abi_size] }, | ||
| 17856 | } })), | ||
| 17857 | }); | ||
| 17858 | const rhs_mask_mem: Memory = .{ | 17831 | const rhs_mask_mem: Memory = .{ |
| 17859 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, rhs_mask_mcv.address()) }, | 17832 | .base = .{ .reg = try self.copyToTmpRegister(Type.usize, rhs_mask_mcv.address()) }, |
| 17860 | .mod = .{ .rm = .{ .size = Memory.Size.fromSize(@max(max_abi_size, 16)) } }, | 17833 | .mod = .{ .rm = .{ .size = Memory.Size.fromSize(@max(max_abi_size, 16)) } }, |
| ... | @@ -17903,11 +17876,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -17903,11 +17876,8 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 17903 | 17876 | ||
| 17904 | break :result null; | 17877 | break :result null; |
| 17905 | }) orelse return self.fail("TODO implement airShuffle from {} and {} to {} with {}", .{ | 17878 | }) orelse return self.fail("TODO implement airShuffle from {} and {} to {} with {}", .{ |
| 17906 | lhs_ty.fmt(mod), rhs_ty.fmt(mod), dst_ty.fmt(mod), | 17879 | lhs_ty.fmt(mod), rhs_ty.fmt(mod), dst_ty.fmt(mod), |
| 17907 | Value.fromInterned(extra.mask).fmtValue( | 17880 | Value.fromInterned(extra.mask).fmtValue(mod), |
| 17908 | Type.fromInterned(mod.intern_pool.typeOf(extra.mask)), | ||
| 17909 | mod, | ||
| 17910 | ), | ||
| 17911 | }); | 17881 | }); |
| 17912 | return self.finishAir(inst, result, .{ extra.a, extra.b, .none }); | 17882 | return self.finishAir(inst, result, .{ extra.a, extra.b, .none }); |
| 17913 | } | 17883 | } |
| ... | @@ -18140,7 +18110,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18140,7 +18110,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 18140 | .{ .frame = frame_index }, | 18110 | .{ .frame = frame_index }, |
| 18141 | @intCast(elem_size * elements.len), | 18111 | @intCast(elem_size * elements.len), |
| 18142 | elem_ty, | 18112 | elem_ty, |
| 18143 | try self.genTypedValue(.{ .ty = elem_ty, .val = sentinel }), | 18113 | try self.genTypedValue(sentinel), |
| 18144 | .{}, | 18114 | .{}, |
| 18145 | ); | 18115 | ); |
| 18146 | break :result .{ .load_frame = .{ .index = frame_index } }; | 18116 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| ... | @@ -18664,7 +18634,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -18664,7 +18634,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { |
| 18664 | const ip_index = ref.toInterned().?; | 18634 | const ip_index = ref.toInterned().?; |
| 18665 | const gop = try self.const_tracking.getOrPut(self.gpa, ip_index); | 18635 | const gop = try self.const_tracking.getOrPut(self.gpa, ip_index); |
| 18666 | if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(init: { | 18636 | if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(init: { |
| 18667 | const const_mcv = try self.genTypedValue(.{ .ty = ty, .val = Value.fromInterned(ip_index) }); | 18637 | const const_mcv = try self.genTypedValue(Value.fromInterned(ip_index)); |
| 18668 | switch (const_mcv) { | 18638 | switch (const_mcv) { |
| 18669 | .lea_tlv => |tlv_sym| switch (self.bin_file.tag) { | 18639 | .lea_tlv => |tlv_sym| switch (self.bin_file.tag) { |
| 18670 | .elf, .macho => { | 18640 | .elf, .macho => { |
| ... | @@ -18729,9 +18699,9 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV | ... | @@ -18729,9 +18699,9 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV |
| 18729 | return mcv; | 18699 | return mcv; |
| 18730 | } | 18700 | } |
| 18731 | 18701 | ||
| 18732 | fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { | 18702 | fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { |
| 18733 | const mod = self.bin_file.comp.module.?; | 18703 | const mod = self.bin_file.comp.module.?; |
| 18734 | return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, arg_tv, self.owner.getDecl(mod))) { | 18704 | return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, val, self.owner.getDecl(mod))) { |
| 18735 | .mcv => |mcv| switch (mcv) { | 18705 | .mcv => |mcv| switch (mcv) { |
| 18736 | .none => .none, | 18706 | .none => .none, |
| 18737 | .undef => .undef, | 18707 | .undef => .undef, |
src/codegen.zig+123-177| ... | @@ -19,7 +19,6 @@ const Liveness = @import("Liveness.zig"); | ... | @@ -19,7 +19,6 @@ const Liveness = @import("Liveness.zig"); |
| 19 | const Module = @import("Module.zig"); | 19 | const Module = @import("Module.zig"); |
| 20 | const Target = std.Target; | 20 | const Target = std.Target; |
| 21 | const Type = @import("type.zig").Type; | 21 | const Type = @import("type.zig").Type; |
| 22 | const TypedValue = @import("TypedValue.zig"); | ||
| 23 | const Value = @import("Value.zig"); | 22 | const Value = @import("Value.zig"); |
| 24 | const Zir = std.zig.Zir; | 23 | const Zir = std.zig.Zir; |
| 25 | const Alignment = InternPool.Alignment; | 24 | const Alignment = InternPool.Alignment; |
| ... | @@ -171,7 +170,7 @@ pub fn generateLazySymbol( | ... | @@ -171,7 +170,7 @@ pub fn generateLazySymbol( |
| 171 | pub fn generateSymbol( | 170 | pub fn generateSymbol( |
| 172 | bin_file: *link.File, | 171 | bin_file: *link.File, |
| 173 | src_loc: Module.SrcLoc, | 172 | src_loc: Module.SrcLoc, |
| 174 | arg_tv: TypedValue, | 173 | val: Value, |
| 175 | code: *std.ArrayList(u8), | 174 | code: *std.ArrayList(u8), |
| 176 | debug_output: DebugInfoOutput, | 175 | debug_output: DebugInfoOutput, |
| 177 | reloc_info: RelocInfo, | 176 | reloc_info: RelocInfo, |
| ... | @@ -181,23 +180,20 @@ pub fn generateSymbol( | ... | @@ -181,23 +180,20 @@ pub fn generateSymbol( |
| 181 | 180 | ||
| 182 | const mod = bin_file.comp.module.?; | 181 | const mod = bin_file.comp.module.?; |
| 183 | const ip = &mod.intern_pool; | 182 | const ip = &mod.intern_pool; |
| 184 | const typed_value = arg_tv; | 183 | const ty = val.typeOf(mod); |
| 185 | 184 | ||
| 186 | const target = mod.getTarget(); | 185 | const target = mod.getTarget(); |
| 187 | const endian = target.cpu.arch.endian(); | 186 | const endian = target.cpu.arch.endian(); |
| 188 | 187 | ||
| 189 | log.debug("generateSymbol: ty = {}, val = {}", .{ | 188 | log.debug("generateSymbol: val = {}", .{val.fmtValue(mod)}); |
| 190 | typed_value.ty.fmt(mod), | ||
| 191 | typed_value.val.fmtValue(typed_value.ty, mod), | ||
| 192 | }); | ||
| 193 | 189 | ||
| 194 | if (typed_value.val.isUndefDeep(mod)) { | 190 | if (val.isUndefDeep(mod)) { |
| 195 | const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow; | 191 | const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow; |
| 196 | try code.appendNTimes(0xaa, abi_size); | 192 | try code.appendNTimes(0xaa, abi_size); |
| 197 | return .ok; | 193 | return .ok; |
| 198 | } | 194 | } |
| 199 | 195 | ||
| 200 | switch (ip.indexToKey(typed_value.val.toIntern())) { | 196 | switch (ip.indexToKey(val.toIntern())) { |
| 201 | .int_type, | 197 | .int_type, |
| 202 | .ptr_type, | 198 | .ptr_type, |
| 203 | .array_type, | 199 | .array_type, |
| ... | @@ -238,17 +234,17 @@ pub fn generateSymbol( | ... | @@ -238,17 +234,17 @@ pub fn generateSymbol( |
| 238 | .empty_enum_value, | 234 | .empty_enum_value, |
| 239 | => unreachable, // non-runtime values | 235 | => unreachable, // non-runtime values |
| 240 | .int => { | 236 | .int => { |
| 241 | const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow; | 237 | const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow; |
| 242 | var space: Value.BigIntSpace = undefined; | 238 | var space: Value.BigIntSpace = undefined; |
| 243 | const val = typed_value.val.toBigInt(&space, mod); | 239 | const int_val = val.toBigInt(&space, mod); |
| 244 | val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian); | 240 | int_val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian); |
| 245 | }, | 241 | }, |
| 246 | .err => |err| { | 242 | .err => |err| { |
| 247 | const int = try mod.getErrorValue(err.name); | 243 | const int = try mod.getErrorValue(err.name); |
| 248 | try code.writer().writeInt(u16, @as(u16, @intCast(int)), endian); | 244 | try code.writer().writeInt(u16, @as(u16, @intCast(int)), endian); |
| 249 | }, | 245 | }, |
| 250 | .error_union => |error_union| { | 246 | .error_union => |error_union| { |
| 251 | const payload_ty = typed_value.ty.errorUnionPayload(mod); | 247 | const payload_ty = ty.errorUnionPayload(mod); |
| 252 | const err_val = switch (error_union.val) { | 248 | const err_val = switch (error_union.val) { |
| 253 | .err_name => |err_name| @as(u16, @intCast(try mod.getErrorValue(err_name))), | 249 | .err_name => |err_name| @as(u16, @intCast(try mod.getErrorValue(err_name))), |
| 254 | .payload => @as(u16, 0), | 250 | .payload => @as(u16, 0), |
| ... | @@ -261,7 +257,7 @@ pub fn generateSymbol( | ... | @@ -261,7 +257,7 @@ pub fn generateSymbol( |
| 261 | 257 | ||
| 262 | const payload_align = payload_ty.abiAlignment(mod); | 258 | const payload_align = payload_ty.abiAlignment(mod); |
| 263 | const error_align = Type.anyerror.abiAlignment(mod); | 259 | const error_align = Type.anyerror.abiAlignment(mod); |
| 264 | const abi_align = typed_value.ty.abiAlignment(mod); | 260 | const abi_align = ty.abiAlignment(mod); |
| 265 | 261 | ||
| 266 | // error value first when its type is larger than the error union's payload | 262 | // error value first when its type is larger than the error union's payload |
| 267 | if (error_align.order(payload_align) == .gt) { | 263 | if (error_align.order(payload_align) == .gt) { |
| ... | @@ -271,13 +267,10 @@ pub fn generateSymbol( | ... | @@ -271,13 +267,10 @@ pub fn generateSymbol( |
| 271 | // emit payload part of the error union | 267 | // emit payload part of the error union |
| 272 | { | 268 | { |
| 273 | const begin = code.items.len; | 269 | const begin = code.items.len; |
| 274 | switch (try generateSymbol(bin_file, src_loc, .{ | 270 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(switch (error_union.val) { |
| 275 | .ty = payload_ty, | 271 | .err_name => try mod.intern(.{ .undef = payload_ty.toIntern() }), |
| 276 | .val = Value.fromInterned(switch (error_union.val) { | 272 | .payload => |payload| payload, |
| 277 | .err_name => try mod.intern(.{ .undef = payload_ty.toIntern() }), | 273 | }), code, debug_output, reloc_info)) { |
| 278 | .payload => |payload| payload, | ||
| 279 | }), | ||
| 280 | }, code, debug_output, reloc_info)) { | ||
| 281 | .ok => {}, | 274 | .ok => {}, |
| 282 | .fail => |em| return .{ .fail = em }, | 275 | .fail => |em| return .{ .fail = em }, |
| 283 | } | 276 | } |
| ... | @@ -304,11 +297,8 @@ pub fn generateSymbol( | ... | @@ -304,11 +297,8 @@ pub fn generateSymbol( |
| 304 | } | 297 | } |
| 305 | }, | 298 | }, |
| 306 | .enum_tag => |enum_tag| { | 299 | .enum_tag => |enum_tag| { |
| 307 | const int_tag_ty = typed_value.ty.intTagType(mod); | 300 | const int_tag_ty = ty.intTagType(mod); |
| 308 | switch (try generateSymbol(bin_file, src_loc, .{ | 301 | switch (try generateSymbol(bin_file, src_loc, try mod.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, debug_output, reloc_info)) { |
| 309 | .ty = int_tag_ty, | ||
| 310 | .val = try mod.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), | ||
| 311 | }, code, debug_output, reloc_info)) { | ||
| 312 | .ok => {}, | 302 | .ok => {}, |
| 313 | .fail => |em| return .{ .fail = em }, | 303 | .fail => |em| return .{ .fail = em }, |
| 314 | } | 304 | } |
| ... | @@ -319,42 +309,33 @@ pub fn generateSymbol( | ... | @@ -319,42 +309,33 @@ pub fn generateSymbol( |
| 319 | .f64 => |f64_val| writeFloat(f64, f64_val, target, endian, try code.addManyAsArray(8)), | 309 | .f64 => |f64_val| writeFloat(f64, f64_val, target, endian, try code.addManyAsArray(8)), |
| 320 | .f80 => |f80_val| { | 310 | .f80 => |f80_val| { |
| 321 | writeFloat(f80, f80_val, target, endian, try code.addManyAsArray(10)); | 311 | writeFloat(f80, f80_val, target, endian, try code.addManyAsArray(10)); |
| 322 | const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow; | 312 | const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow; |
| 323 | try code.appendNTimes(0, abi_size - 10); | 313 | try code.appendNTimes(0, abi_size - 10); |
| 324 | }, | 314 | }, |
| 325 | .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)), | 315 | .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)), |
| 326 | }, | 316 | }, |
| 327 | .ptr => switch (try lowerParentPtr(bin_file, src_loc, typed_value.val.toIntern(), code, debug_output, reloc_info)) { | 317 | .ptr => switch (try lowerParentPtr(bin_file, src_loc, val.toIntern(), code, debug_output, reloc_info)) { |
| 328 | .ok => {}, | 318 | .ok => {}, |
| 329 | .fail => |em| return .{ .fail = em }, | 319 | .fail => |em| return .{ .fail = em }, |
| 330 | }, | 320 | }, |
| 331 | .slice => |slice| { | 321 | .slice => |slice| { |
| 332 | switch (try generateSymbol(bin_file, src_loc, .{ | 322 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(slice.ptr), code, debug_output, reloc_info)) { |
| 333 | .ty = typed_value.ty.slicePtrFieldType(mod), | ||
| 334 | .val = Value.fromInterned(slice.ptr), | ||
| 335 | }, code, debug_output, reloc_info)) { | ||
| 336 | .ok => {}, | 323 | .ok => {}, |
| 337 | .fail => |em| return .{ .fail = em }, | 324 | .fail => |em| return .{ .fail = em }, |
| 338 | } | 325 | } |
| 339 | switch (try generateSymbol(bin_file, src_loc, .{ | 326 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(slice.len), code, debug_output, reloc_info)) { |
| 340 | .ty = Type.usize, | ||
| 341 | .val = Value.fromInterned(slice.len), | ||
| 342 | }, code, debug_output, reloc_info)) { | ||
| 343 | .ok => {}, | 327 | .ok => {}, |
| 344 | .fail => |em| return .{ .fail = em }, | 328 | .fail => |em| return .{ .fail = em }, |
| 345 | } | 329 | } |
| 346 | }, | 330 | }, |
| 347 | .opt => { | 331 | .opt => { |
| 348 | const payload_type = typed_value.ty.optionalChild(mod); | 332 | const payload_type = ty.optionalChild(mod); |
| 349 | const payload_val = typed_value.val.optionalValue(mod); | 333 | const payload_val = val.optionalValue(mod); |
| 350 | const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow; | 334 | const abi_size = math.cast(usize, ty.abiSize(mod)) orelse return error.Overflow; |
| 351 | 335 | ||
| 352 | if (typed_value.ty.optionalReprIsPayload(mod)) { | 336 | if (ty.optionalReprIsPayload(mod)) { |
| 353 | if (payload_val) |value| { | 337 | if (payload_val) |value| { |
| 354 | switch (try generateSymbol(bin_file, src_loc, .{ | 338 | switch (try generateSymbol(bin_file, src_loc, value, code, debug_output, reloc_info)) { |
| 355 | .ty = payload_type, | ||
| 356 | .val = value, | ||
| 357 | }, code, debug_output, reloc_info)) { | ||
| 358 | .ok => {}, | 339 | .ok => {}, |
| 359 | .fail => |em| return Result{ .fail = em }, | 340 | .fail => |em| return Result{ .fail = em }, |
| 360 | } | 341 | } |
| ... | @@ -365,10 +346,7 @@ pub fn generateSymbol( | ... | @@ -365,10 +346,7 @@ pub fn generateSymbol( |
| 365 | const padding = abi_size - (math.cast(usize, payload_type.abiSize(mod)) orelse return error.Overflow) - 1; | 346 | const padding = abi_size - (math.cast(usize, payload_type.abiSize(mod)) orelse return error.Overflow) - 1; |
| 366 | if (payload_type.hasRuntimeBits(mod)) { | 347 | if (payload_type.hasRuntimeBits(mod)) { |
| 367 | const value = payload_val orelse Value.fromInterned((try mod.intern(.{ .undef = payload_type.toIntern() }))); | 348 | const value = payload_val orelse Value.fromInterned((try mod.intern(.{ .undef = payload_type.toIntern() }))); |
| 368 | switch (try generateSymbol(bin_file, src_loc, .{ | 349 | switch (try generateSymbol(bin_file, src_loc, value, code, debug_output, reloc_info)) { |
| 369 | .ty = payload_type, | ||
| 370 | .val = value, | ||
| 371 | }, code, debug_output, reloc_info)) { | ||
| 372 | .ok => {}, | 350 | .ok => {}, |
| 373 | .fail => |em| return Result{ .fail = em }, | 351 | .fail => |em| return Result{ .fail = em }, |
| 374 | } | 352 | } |
| ... | @@ -377,7 +355,7 @@ pub fn generateSymbol( | ... | @@ -377,7 +355,7 @@ pub fn generateSymbol( |
| 377 | try code.appendNTimes(0, padding); | 355 | try code.appendNTimes(0, padding); |
| 378 | } | 356 | } |
| 379 | }, | 357 | }, |
| 380 | .aggregate => |aggregate| switch (ip.indexToKey(typed_value.ty.toIntern())) { | 358 | .aggregate => |aggregate| switch (ip.indexToKey(ty.toIntern())) { |
| 381 | .array_type => |array_type| switch (aggregate.storage) { | 359 | .array_type => |array_type| switch (aggregate.storage) { |
| 382 | .bytes => |bytes| try code.appendSlice(bytes), | 360 | .bytes => |bytes| try code.appendSlice(bytes), |
| 383 | .elems, .repeated_elem => { | 361 | .elems, .repeated_elem => { |
| ... | @@ -385,17 +363,14 @@ pub fn generateSymbol( | ... | @@ -385,17 +363,14 @@ pub fn generateSymbol( |
| 385 | const len_including_sentinel = | 363 | const len_including_sentinel = |
| 386 | array_type.len + @intFromBool(array_type.sentinel != .none); | 364 | array_type.len + @intFromBool(array_type.sentinel != .none); |
| 387 | while (index < len_including_sentinel) : (index += 1) { | 365 | while (index < len_including_sentinel) : (index += 1) { |
| 388 | switch (try generateSymbol(bin_file, src_loc, .{ | 366 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(switch (aggregate.storage) { |
| 389 | .ty = Type.fromInterned(array_type.child), | 367 | .bytes => unreachable, |
| 390 | .val = Value.fromInterned(switch (aggregate.storage) { | 368 | .elems => |elems| elems[@as(usize, @intCast(index))], |
| 391 | .bytes => unreachable, | 369 | .repeated_elem => |elem| if (index < array_type.len) |
| 392 | .elems => |elems| elems[@as(usize, @intCast(index))], | 370 | elem |
| 393 | .repeated_elem => |elem| if (index < array_type.len) | 371 | else |
| 394 | elem | 372 | array_type.sentinel, |
| 395 | else | 373 | }), code, debug_output, reloc_info)) { |
| 396 | array_type.sentinel, | ||
| 397 | }), | ||
| 398 | }, code, debug_output, reloc_info)) { | ||
| 399 | .ok => {}, | 374 | .ok => {}, |
| 400 | .fail => |em| return .{ .fail = em }, | 375 | .fail => |em| return .{ .fail = em }, |
| 401 | } | 376 | } |
| ... | @@ -403,7 +378,7 @@ pub fn generateSymbol( | ... | @@ -403,7 +378,7 @@ pub fn generateSymbol( |
| 403 | }, | 378 | }, |
| 404 | }, | 379 | }, |
| 405 | .vector_type => |vector_type| { | 380 | .vector_type => |vector_type| { |
| 406 | const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse | 381 | const abi_size = math.cast(usize, ty.abiSize(mod)) orelse |
| 407 | return error.Overflow; | 382 | return error.Overflow; |
| 408 | if (vector_type.child == .bool_type) { | 383 | if (vector_type.child == .bool_type) { |
| 409 | const bytes = try code.addManyAsSlice(abi_size); | 384 | const bytes = try code.addManyAsSlice(abi_size); |
| ... | @@ -449,16 +424,13 @@ pub fn generateSymbol( | ... | @@ -449,16 +424,13 @@ pub fn generateSymbol( |
| 449 | .elems, .repeated_elem => { | 424 | .elems, .repeated_elem => { |
| 450 | var index: u64 = 0; | 425 | var index: u64 = 0; |
| 451 | while (index < vector_type.len) : (index += 1) { | 426 | while (index < vector_type.len) : (index += 1) { |
| 452 | switch (try generateSymbol(bin_file, src_loc, .{ | 427 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(switch (aggregate.storage) { |
| 453 | .ty = Type.fromInterned(vector_type.child), | 428 | .bytes => unreachable, |
| 454 | .val = Value.fromInterned(switch (aggregate.storage) { | 429 | .elems => |elems| elems[ |
| 455 | .bytes => unreachable, | 430 | math.cast(usize, index) orelse return error.Overflow |
| 456 | .elems => |elems| elems[ | 431 | ], |
| 457 | math.cast(usize, index) orelse return error.Overflow | 432 | .repeated_elem => |elem| elem, |
| 458 | ], | 433 | }), code, debug_output, reloc_info)) { |
| 459 | .repeated_elem => |elem| elem, | ||
| 460 | }), | ||
| 461 | }, code, debug_output, reloc_info)) { | ||
| 462 | .ok => {}, | 434 | .ok => {}, |
| 463 | .fail => |em| return .{ .fail = em }, | 435 | .fail => |em| return .{ .fail = em }, |
| 464 | } | 436 | } |
| ... | @@ -491,17 +463,14 @@ pub fn generateSymbol( | ... | @@ -491,17 +463,14 @@ pub fn generateSymbol( |
| 491 | .repeated_elem => |elem| elem, | 463 | .repeated_elem => |elem| elem, |
| 492 | }; | 464 | }; |
| 493 | 465 | ||
| 494 | switch (try generateSymbol(bin_file, src_loc, .{ | 466 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(field_val), code, debug_output, reloc_info)) { |
| 495 | .ty = Type.fromInterned(field_ty), | ||
| 496 | .val = Value.fromInterned(field_val), | ||
| 497 | }, code, debug_output, reloc_info)) { | ||
| 498 | .ok => {}, | 467 | .ok => {}, |
| 499 | .fail => |em| return Result{ .fail = em }, | 468 | .fail => |em| return Result{ .fail = em }, |
| 500 | } | 469 | } |
| 501 | const unpadded_field_end = code.items.len - struct_begin; | 470 | const unpadded_field_end = code.items.len - struct_begin; |
| 502 | 471 | ||
| 503 | // Pad struct members if required | 472 | // Pad struct members if required |
| 504 | const padded_field_end = typed_value.ty.structFieldOffset(index + 1, mod); | 473 | const padded_field_end = ty.structFieldOffset(index + 1, mod); |
| 505 | const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse | 474 | const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse |
| 506 | return error.Overflow; | 475 | return error.Overflow; |
| 507 | 476 | ||
| ... | @@ -511,10 +480,10 @@ pub fn generateSymbol( | ... | @@ -511,10 +480,10 @@ pub fn generateSymbol( |
| 511 | } | 480 | } |
| 512 | }, | 481 | }, |
| 513 | .struct_type => { | 482 | .struct_type => { |
| 514 | const struct_type = ip.loadStructType(typed_value.ty.toIntern()); | 483 | const struct_type = ip.loadStructType(ty.toIntern()); |
| 515 | switch (struct_type.layout) { | 484 | switch (struct_type.layout) { |
| 516 | .@"packed" => { | 485 | .@"packed" => { |
| 517 | const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse | 486 | const abi_size = math.cast(usize, ty.abiSize(mod)) orelse |
| 518 | return error.Overflow; | 487 | return error.Overflow; |
| 519 | const current_pos = code.items.len; | 488 | const current_pos = code.items.len; |
| 520 | try code.resize(current_pos + abi_size); | 489 | try code.resize(current_pos + abi_size); |
| ... | @@ -537,10 +506,7 @@ pub fn generateSymbol( | ... | @@ -537,10 +506,7 @@ pub fn generateSymbol( |
| 537 | return error.Overflow; | 506 | return error.Overflow; |
| 538 | var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size); | 507 | var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size); |
| 539 | defer tmp_list.deinit(); | 508 | defer tmp_list.deinit(); |
| 540 | switch (try generateSymbol(bin_file, src_loc, .{ | 509 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(field_val), &tmp_list, debug_output, reloc_info)) { |
| 541 | .ty = Type.fromInterned(field_ty), | ||
| 542 | .val = Value.fromInterned(field_val), | ||
| 543 | }, &tmp_list, debug_output, reloc_info)) { | ||
| 544 | .ok => @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items), | 510 | .ok => @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items), |
| 545 | .fail => |em| return Result{ .fail = em }, | 511 | .fail => |em| return Result{ .fail = em }, |
| 546 | } | 512 | } |
| ... | @@ -560,7 +526,7 @@ pub fn generateSymbol( | ... | @@ -560,7 +526,7 @@ pub fn generateSymbol( |
| 560 | const field_ty = field_types[field_index]; | 526 | const field_ty = field_types[field_index]; |
| 561 | if (!Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue; | 527 | if (!Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue; |
| 562 | 528 | ||
| 563 | const field_val = switch (ip.indexToKey(typed_value.val.toIntern()).aggregate.storage) { | 529 | const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) { |
| 564 | .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{ | 530 | .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{ |
| 565 | .ty = field_ty, | 531 | .ty = field_ty, |
| 566 | .storage = .{ .u64 = bytes[field_index] }, | 532 | .storage = .{ .u64 = bytes[field_index] }, |
| ... | @@ -575,10 +541,7 @@ pub fn generateSymbol( | ... | @@ -575,10 +541,7 @@ pub fn generateSymbol( |
| 575 | ) orelse return error.Overflow; | 541 | ) orelse return error.Overflow; |
| 576 | if (padding > 0) try code.appendNTimes(0, padding); | 542 | if (padding > 0) try code.appendNTimes(0, padding); |
| 577 | 543 | ||
| 578 | switch (try generateSymbol(bin_file, src_loc, .{ | 544 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(field_val), code, debug_output, reloc_info)) { |
| 579 | .ty = Type.fromInterned(field_ty), | ||
| 580 | .val = Value.fromInterned(field_val), | ||
| 581 | }, code, debug_output, reloc_info)) { | ||
| 582 | .ok => {}, | 545 | .ok => {}, |
| 583 | .fail => |em| return Result{ .fail = em }, | 546 | .fail => |em| return Result{ .fail = em }, |
| 584 | } | 547 | } |
| ... | @@ -599,37 +562,28 @@ pub fn generateSymbol( | ... | @@ -599,37 +562,28 @@ pub fn generateSymbol( |
| 599 | else => unreachable, | 562 | else => unreachable, |
| 600 | }, | 563 | }, |
| 601 | .un => |un| { | 564 | .un => |un| { |
| 602 | const layout = typed_value.ty.unionGetLayout(mod); | 565 | const layout = ty.unionGetLayout(mod); |
| 603 | 566 | ||
| 604 | if (layout.payload_size == 0) { | 567 | if (layout.payload_size == 0) { |
| 605 | return generateSymbol(bin_file, src_loc, .{ | 568 | return generateSymbol(bin_file, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info); |
| 606 | .ty = typed_value.ty.unionTagTypeSafety(mod).?, | ||
| 607 | .val = Value.fromInterned(un.tag), | ||
| 608 | }, code, debug_output, reloc_info); | ||
| 609 | } | 569 | } |
| 610 | 570 | ||
| 611 | // Check if we should store the tag first. | 571 | // Check if we should store the tag first. |
| 612 | if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) { | 572 | if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) { |
| 613 | switch (try generateSymbol(bin_file, src_loc, .{ | 573 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info)) { |
| 614 | .ty = typed_value.ty.unionTagTypeSafety(mod).?, | ||
| 615 | .val = Value.fromInterned(un.tag), | ||
| 616 | }, code, debug_output, reloc_info)) { | ||
| 617 | .ok => {}, | 574 | .ok => {}, |
| 618 | .fail => |em| return Result{ .fail = em }, | 575 | .fail => |em| return Result{ .fail = em }, |
| 619 | } | 576 | } |
| 620 | } | 577 | } |
| 621 | 578 | ||
| 622 | const union_obj = mod.typeToUnion(typed_value.ty).?; | 579 | const union_obj = mod.typeToUnion(ty).?; |
| 623 | if (un.tag != .none) { | 580 | if (un.tag != .none) { |
| 624 | const field_index = typed_value.ty.unionTagFieldIndex(Value.fromInterned(un.tag), mod).?; | 581 | const field_index = ty.unionTagFieldIndex(Value.fromInterned(un.tag), mod).?; |
| 625 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 582 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 626 | if (!field_ty.hasRuntimeBits(mod)) { | 583 | if (!field_ty.hasRuntimeBits(mod)) { |
| 627 | try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow); | 584 | try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow); |
| 628 | } else { | 585 | } else { |
| 629 | switch (try generateSymbol(bin_file, src_loc, .{ | 586 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.val), code, debug_output, reloc_info)) { |
| 630 | .ty = field_ty, | ||
| 631 | .val = Value.fromInterned(un.val), | ||
| 632 | }, code, debug_output, reloc_info)) { | ||
| 633 | .ok => {}, | 587 | .ok => {}, |
| 634 | .fail => |em| return Result{ .fail = em }, | 588 | .fail => |em| return Result{ .fail = em }, |
| 635 | } | 589 | } |
| ... | @@ -640,20 +594,14 @@ pub fn generateSymbol( | ... | @@ -640,20 +594,14 @@ pub fn generateSymbol( |
| 640 | } | 594 | } |
| 641 | } | 595 | } |
| 642 | } else { | 596 | } else { |
| 643 | switch (try generateSymbol(bin_file, src_loc, .{ | 597 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.val), code, debug_output, reloc_info)) { |
| 644 | .ty = Type.fromInterned(ip.typeOf(un.val)), | ||
| 645 | .val = Value.fromInterned(un.val), | ||
| 646 | }, code, debug_output, reloc_info)) { | ||
| 647 | .ok => {}, | 598 | .ok => {}, |
| 648 | .fail => |em| return Result{ .fail = em }, | 599 | .fail => |em| return Result{ .fail = em }, |
| 649 | } | 600 | } |
| 650 | } | 601 | } |
| 651 | 602 | ||
| 652 | if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) { | 603 | if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) { |
| 653 | switch (try generateSymbol(bin_file, src_loc, .{ | 604 | switch (try generateSymbol(bin_file, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info)) { |
| 654 | .ty = Type.fromInterned(union_obj.enum_tag_ty), | ||
| 655 | .val = Value.fromInterned(un.tag), | ||
| 656 | }, code, debug_output, reloc_info)) { | ||
| 657 | .ok => {}, | 605 | .ok => {}, |
| 658 | .fail => |em| return Result{ .fail = em }, | 606 | .fail => |em| return Result{ .fail = em }, |
| 659 | } | 607 | } |
| ... | @@ -681,10 +629,7 @@ fn lowerParentPtr( | ... | @@ -681,10 +629,7 @@ fn lowerParentPtr( |
| 681 | return switch (ptr.addr) { | 629 | return switch (ptr.addr) { |
| 682 | .decl => |decl| try lowerDeclRef(bin_file, src_loc, decl, code, debug_output, reloc_info), | 630 | .decl => |decl| try lowerDeclRef(bin_file, src_loc, decl, code, debug_output, reloc_info), |
| 683 | .anon_decl => |ad| try lowerAnonDeclRef(bin_file, src_loc, ad, code, debug_output, reloc_info), | 631 | .anon_decl => |ad| try lowerAnonDeclRef(bin_file, src_loc, ad, code, debug_output, reloc_info), |
| 684 | .int => |int| try generateSymbol(bin_file, src_loc, .{ | 632 | .int => |int| try generateSymbol(bin_file, src_loc, Value.fromInterned(int), code, debug_output, reloc_info), |
| 685 | .ty = Type.usize, | ||
| 686 | .val = Value.fromInterned(int), | ||
| 687 | }, code, debug_output, reloc_info), | ||
| 688 | .eu_payload => |eu_payload| try lowerParentPtr( | 633 | .eu_payload => |eu_payload| try lowerParentPtr( |
| 689 | bin_file, | 634 | bin_file, |
| 690 | src_loc, | 635 | src_loc, |
| ... | @@ -829,14 +774,12 @@ fn lowerDeclRef( | ... | @@ -829,14 +774,12 @@ fn lowerDeclRef( |
| 829 | const target = namespace.file_scope.mod.resolved_target.result; | 774 | const target = namespace.file_scope.mod.resolved_target.result; |
| 830 | 775 | ||
| 831 | const ptr_width = target.ptrBitWidth(); | 776 | const ptr_width = target.ptrBitWidth(); |
| 832 | const is_fn_body = decl.ty.zigTypeTag(zcu) == .Fn; | 777 | const is_fn_body = decl.typeOf(zcu).zigTypeTag(zcu) == .Fn; |
| 833 | if (!is_fn_body and !decl.ty.hasRuntimeBits(zcu)) { | 778 | if (!is_fn_body and !decl.typeOf(zcu).hasRuntimeBits(zcu)) { |
| 834 | try code.appendNTimes(0xaa, @divExact(ptr_width, 8)); | 779 | try code.appendNTimes(0xaa, @divExact(ptr_width, 8)); |
| 835 | return Result.ok; | 780 | return Result.ok; |
| 836 | } | 781 | } |
| 837 | 782 | ||
| 838 | try zcu.markDeclAlive(decl); | ||
| 839 | |||
| 840 | const vaddr = try lf.getDeclVAddr(decl_index, .{ | 783 | const vaddr = try lf.getDeclVAddr(decl_index, .{ |
| 841 | .parent_atom_index = reloc_info.parent_atom_index, | 784 | .parent_atom_index = reloc_info.parent_atom_index, |
| 842 | .offset = code.items.len, | 785 | .offset = code.items.len, |
| ... | @@ -912,11 +855,12 @@ pub const GenResult = union(enum) { | ... | @@ -912,11 +855,12 @@ pub const GenResult = union(enum) { |
| 912 | fn genDeclRef( | 855 | fn genDeclRef( |
| 913 | lf: *link.File, | 856 | lf: *link.File, |
| 914 | src_loc: Module.SrcLoc, | 857 | src_loc: Module.SrcLoc, |
| 915 | tv: TypedValue, | 858 | val: Value, |
| 916 | ptr_decl_index: InternPool.DeclIndex, | 859 | ptr_decl_index: InternPool.DeclIndex, |
| 917 | ) CodeGenError!GenResult { | 860 | ) CodeGenError!GenResult { |
| 918 | const zcu = lf.comp.module.?; | 861 | const zcu = lf.comp.module.?; |
| 919 | log.debug("genDeclRef: ty = {}, val = {}", .{ tv.ty.fmt(zcu), tv.val.fmtValue(tv.ty, zcu) }); | 862 | const ty = val.typeOf(zcu); |
| 863 | log.debug("genDeclRef: val = {}", .{val.fmtValue(zcu)}); | ||
| 920 | 864 | ||
| 921 | const ptr_decl = zcu.declPtr(ptr_decl_index); | 865 | const ptr_decl = zcu.declPtr(ptr_decl_index); |
| 922 | const namespace = zcu.namespacePtr(ptr_decl.src_namespace); | 866 | const namespace = zcu.namespacePtr(ptr_decl.src_namespace); |
| ... | @@ -925,14 +869,14 @@ fn genDeclRef( | ... | @@ -925,14 +869,14 @@ fn genDeclRef( |
| 925 | const ptr_bits = target.ptrBitWidth(); | 869 | const ptr_bits = target.ptrBitWidth(); |
| 926 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); | 870 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); |
| 927 | 871 | ||
| 928 | const decl_index = switch (zcu.intern_pool.indexToKey(try ptr_decl.internValue(zcu))) { | 872 | const decl_index = switch (zcu.intern_pool.indexToKey(ptr_decl.val.toIntern())) { |
| 929 | .func => |func| func.owner_decl, | 873 | .func => |func| func.owner_decl, |
| 930 | .extern_func => |extern_func| extern_func.decl, | 874 | .extern_func => |extern_func| extern_func.decl, |
| 931 | else => ptr_decl_index, | 875 | else => ptr_decl_index, |
| 932 | }; | 876 | }; |
| 933 | const decl = zcu.declPtr(decl_index); | 877 | const decl = zcu.declPtr(decl_index); |
| 934 | 878 | ||
| 935 | if (!decl.ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) { | 879 | if (!decl.typeOf(zcu).isFnOrHasRuntimeBitsIgnoreComptime(zcu)) { |
| 936 | const imm: u64 = switch (ptr_bytes) { | 880 | const imm: u64 = switch (ptr_bytes) { |
| 937 | 1 => 0xaa, | 881 | 1 => 0xaa, |
| 938 | 2 => 0xaaaa, | 882 | 2 => 0xaaaa, |
| ... | @@ -947,22 +891,20 @@ fn genDeclRef( | ... | @@ -947,22 +891,20 @@ fn genDeclRef( |
| 947 | const gpa = comp.gpa; | 891 | const gpa = comp.gpa; |
| 948 | 892 | ||
| 949 | // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`? | 893 | // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`? |
| 950 | if (tv.ty.castPtrToFn(zcu)) |fn_ty| { | 894 | if (ty.castPtrToFn(zcu)) |fn_ty| { |
| 951 | if (zcu.typeToFunc(fn_ty).?.is_generic) { | 895 | if (zcu.typeToFunc(fn_ty).?.is_generic) { |
| 952 | return GenResult.mcv(.{ .immediate = fn_ty.abiAlignment(zcu).toByteUnitsOptional().? }); | 896 | return GenResult.mcv(.{ .immediate = fn_ty.abiAlignment(zcu).toByteUnitsOptional().? }); |
| 953 | } | 897 | } |
| 954 | } else if (tv.ty.zigTypeTag(zcu) == .Pointer) { | 898 | } else if (ty.zigTypeTag(zcu) == .Pointer) { |
| 955 | const elem_ty = tv.ty.elemType2(zcu); | 899 | const elem_ty = ty.elemType2(zcu); |
| 956 | if (!elem_ty.hasRuntimeBits(zcu)) { | 900 | if (!elem_ty.hasRuntimeBits(zcu)) { |
| 957 | return GenResult.mcv(.{ .immediate = elem_ty.abiAlignment(zcu).toByteUnitsOptional().? }); | 901 | return GenResult.mcv(.{ .immediate = elem_ty.abiAlignment(zcu).toByteUnitsOptional().? }); |
| 958 | } | 902 | } |
| 959 | } | 903 | } |
| 960 | 904 | ||
| 961 | try zcu.markDeclAlive(decl); | ||
| 962 | |||
| 963 | const decl_namespace = zcu.namespacePtr(decl.src_namespace); | 905 | const decl_namespace = zcu.namespacePtr(decl.src_namespace); |
| 964 | const single_threaded = decl_namespace.file_scope.mod.single_threaded; | 906 | const single_threaded = decl_namespace.file_scope.mod.single_threaded; |
| 965 | const is_threadlocal = tv.val.isPtrToThreadLocal(zcu) and !single_threaded; | 907 | const is_threadlocal = val.isPtrToThreadLocal(zcu) and !single_threaded; |
| 966 | const is_extern = decl.isExtern(zcu); | 908 | const is_extern = decl.isExtern(zcu); |
| 967 | 909 | ||
| 968 | if (lf.cast(link.File.Elf)) |elf_file| { | 910 | if (lf.cast(link.File.Elf)) |elf_file| { |
| ... | @@ -1027,14 +969,14 @@ fn genDeclRef( | ... | @@ -1027,14 +969,14 @@ fn genDeclRef( |
| 1027 | fn genUnnamedConst( | 969 | fn genUnnamedConst( |
| 1028 | lf: *link.File, | 970 | lf: *link.File, |
| 1029 | src_loc: Module.SrcLoc, | 971 | src_loc: Module.SrcLoc, |
| 1030 | tv: TypedValue, | 972 | val: Value, |
| 1031 | owner_decl_index: InternPool.DeclIndex, | 973 | owner_decl_index: InternPool.DeclIndex, |
| 1032 | ) CodeGenError!GenResult { | 974 | ) CodeGenError!GenResult { |
| 1033 | const zcu = lf.comp.module.?; | 975 | const zcu = lf.comp.module.?; |
| 1034 | const gpa = lf.comp.gpa; | 976 | const gpa = lf.comp.gpa; |
| 1035 | log.debug("genUnnamedConst: ty = {}, val = {}", .{ tv.ty.fmt(zcu), tv.val.fmtValue(tv.ty, zcu) }); | 977 | log.debug("genUnnamedConst: val = {}", .{val.fmtValue(zcu)}); |
| 1036 | 978 | ||
| 1037 | const local_sym_index = lf.lowerUnnamedConst(tv, owner_decl_index) catch |err| { | 979 | const local_sym_index = lf.lowerUnnamedConst(val, owner_decl_index) catch |err| { |
| 1038 | return GenResult.fail(gpa, src_loc, "lowering unnamed constant failed: {s}", .{@errorName(err)}); | 980 | return GenResult.fail(gpa, src_loc, "lowering unnamed constant failed: {s}", .{@errorName(err)}); |
| 1039 | }; | 981 | }; |
| 1040 | switch (lf.tag) { | 982 | switch (lf.tag) { |
| ... | @@ -1066,18 +1008,15 @@ fn genUnnamedConst( | ... | @@ -1066,18 +1008,15 @@ fn genUnnamedConst( |
| 1066 | pub fn genTypedValue( | 1008 | pub fn genTypedValue( |
| 1067 | lf: *link.File, | 1009 | lf: *link.File, |
| 1068 | src_loc: Module.SrcLoc, | 1010 | src_loc: Module.SrcLoc, |
| 1069 | arg_tv: TypedValue, | 1011 | val: Value, |
| 1070 | owner_decl_index: InternPool.DeclIndex, | 1012 | owner_decl_index: InternPool.DeclIndex, |
| 1071 | ) CodeGenError!GenResult { | 1013 | ) CodeGenError!GenResult { |
| 1072 | const zcu = lf.comp.module.?; | 1014 | const zcu = lf.comp.module.?; |
| 1073 | const typed_value = arg_tv; | 1015 | const ty = val.typeOf(zcu); |
| 1074 | 1016 | ||
| 1075 | log.debug("genTypedValue: ty = {}, val = {}", .{ | 1017 | log.debug("genTypedValue: val = {}", .{val.fmtValue(zcu)}); |
| 1076 | typed_value.ty.fmt(zcu), | ||
| 1077 | typed_value.val.fmtValue(typed_value.ty, zcu), | ||
| 1078 | }); | ||
| 1079 | 1018 | ||
| 1080 | if (typed_value.val.isUndef(zcu)) | 1019 | if (val.isUndef(zcu)) |
| 1081 | return GenResult.mcv(.undef); | 1020 | return GenResult.mcv(.undef); |
| 1082 | 1021 | ||
| 1083 | const owner_decl = zcu.declPtr(owner_decl_index); | 1022 | const owner_decl = zcu.declPtr(owner_decl_index); |
| ... | @@ -1085,85 +1024,92 @@ pub fn genTypedValue( | ... | @@ -1085,85 +1024,92 @@ pub fn genTypedValue( |
| 1085 | const target = namespace.file_scope.mod.resolved_target.result; | 1024 | const target = namespace.file_scope.mod.resolved_target.result; |
| 1086 | const ptr_bits = target.ptrBitWidth(); | 1025 | const ptr_bits = target.ptrBitWidth(); |
| 1087 | 1026 | ||
| 1088 | if (!typed_value.ty.isSlice(zcu)) switch (zcu.intern_pool.indexToKey(typed_value.val.toIntern())) { | 1027 | if (!ty.isSlice(zcu)) switch (zcu.intern_pool.indexToKey(val.toIntern())) { |
| 1089 | .ptr => |ptr| switch (ptr.addr) { | 1028 | .ptr => |ptr| switch (ptr.addr) { |
| 1090 | .decl => |decl| return genDeclRef(lf, src_loc, typed_value, decl), | 1029 | .decl => |decl| return genDeclRef(lf, src_loc, val, decl), |
| 1091 | else => {}, | 1030 | else => {}, |
| 1092 | }, | 1031 | }, |
| 1093 | else => {}, | 1032 | else => {}, |
| 1094 | }; | 1033 | }; |
| 1095 | 1034 | ||
| 1096 | switch (typed_value.ty.zigTypeTag(zcu)) { | 1035 | switch (ty.zigTypeTag(zcu)) { |
| 1097 | .Void => return GenResult.mcv(.none), | 1036 | .Void => return GenResult.mcv(.none), |
| 1098 | .Pointer => switch (typed_value.ty.ptrSize(zcu)) { | 1037 | .Pointer => switch (ty.ptrSize(zcu)) { |
| 1099 | .Slice => {}, | 1038 | .Slice => {}, |
| 1100 | else => switch (typed_value.val.toIntern()) { | 1039 | else => switch (val.toIntern()) { |
| 1101 | .null_value => { | 1040 | .null_value => { |
| 1102 | return GenResult.mcv(.{ .immediate = 0 }); | 1041 | return GenResult.mcv(.{ .immediate = 0 }); |
| 1103 | }, | 1042 | }, |
| 1104 | .none => {}, | 1043 | .none => {}, |
| 1105 | else => switch (zcu.intern_pool.indexToKey(typed_value.val.toIntern())) { | 1044 | else => switch (zcu.intern_pool.indexToKey(val.toIntern())) { |
| 1106 | .int => { | 1045 | .int => { |
| 1107 | return GenResult.mcv(.{ .immediate = typed_value.val.toUnsignedInt(zcu) }); | 1046 | return GenResult.mcv(.{ .immediate = val.toUnsignedInt(zcu) }); |
| 1108 | }, | 1047 | }, |
| 1109 | else => {}, | 1048 | else => {}, |
| 1110 | }, | 1049 | }, |
| 1111 | }, | 1050 | }, |
| 1112 | }, | 1051 | }, |
| 1113 | .Int => { | 1052 | .Int => { |
| 1114 | const info = typed_value.ty.intInfo(zcu); | 1053 | const info = ty.intInfo(zcu); |
| 1115 | if (info.bits <= ptr_bits) { | 1054 | if (info.bits <= ptr_bits) { |
| 1116 | const unsigned = switch (info.signedness) { | 1055 | const unsigned = switch (info.signedness) { |
| 1117 | .signed => @as(u64, @bitCast(typed_value.val.toSignedInt(zcu))), | 1056 | .signed => @as(u64, @bitCast(val.toSignedInt(zcu))), |
| 1118 | .unsigned => typed_value.val.toUnsignedInt(zcu), | 1057 | .unsigned => val.toUnsignedInt(zcu), |
| 1119 | }; | 1058 | }; |
| 1120 | return GenResult.mcv(.{ .immediate = unsigned }); | 1059 | return GenResult.mcv(.{ .immediate = unsigned }); |
| 1121 | } | 1060 | } |
| 1122 | }, | 1061 | }, |
| 1123 | .Bool => { | 1062 | .Bool => { |
| 1124 | return GenResult.mcv(.{ .immediate = @intFromBool(typed_value.val.toBool()) }); | 1063 | return GenResult.mcv(.{ .immediate = @intFromBool(val.toBool()) }); |
| 1125 | }, | 1064 | }, |
| 1126 | .Optional => { | 1065 | .Optional => { |
| 1127 | if (typed_value.ty.isPtrLikeOptional(zcu)) { | 1066 | if (ty.isPtrLikeOptional(zcu)) { |
| 1128 | return genTypedValue(lf, src_loc, .{ | 1067 | return genTypedValue( |
| 1129 | .ty = typed_value.ty.optionalChild(zcu), | 1068 | lf, |
| 1130 | .val = typed_value.val.optionalValue(zcu) orelse return GenResult.mcv(.{ .immediate = 0 }), | 1069 | src_loc, |
| 1131 | }, owner_decl_index); | 1070 | val.optionalValue(zcu) orelse return GenResult.mcv(.{ .immediate = 0 }), |
| 1132 | } else if (typed_value.ty.abiSize(zcu) == 1) { | 1071 | owner_decl_index, |
| 1133 | return GenResult.mcv(.{ .immediate = @intFromBool(!typed_value.val.isNull(zcu)) }); | 1072 | ); |
| 1073 | } else if (ty.abiSize(zcu) == 1) { | ||
| 1074 | return GenResult.mcv(.{ .immediate = @intFromBool(!val.isNull(zcu)) }); | ||
| 1134 | } | 1075 | } |
| 1135 | }, | 1076 | }, |
| 1136 | .Enum => { | 1077 | .Enum => { |
| 1137 | const enum_tag = zcu.intern_pool.indexToKey(typed_value.val.toIntern()).enum_tag; | 1078 | const enum_tag = zcu.intern_pool.indexToKey(val.toIntern()).enum_tag; |
| 1138 | const int_tag_ty = zcu.intern_pool.typeOf(enum_tag.int); | 1079 | return genTypedValue( |
| 1139 | return genTypedValue(lf, src_loc, .{ | 1080 | lf, |
| 1140 | .ty = Type.fromInterned(int_tag_ty), | 1081 | src_loc, |
| 1141 | .val = Value.fromInterned(enum_tag.int), | 1082 | Value.fromInterned(enum_tag.int), |
| 1142 | }, owner_decl_index); | 1083 | owner_decl_index, |
| 1084 | ); | ||
| 1143 | }, | 1085 | }, |
| 1144 | .ErrorSet => { | 1086 | .ErrorSet => { |
| 1145 | const err_name = zcu.intern_pool.indexToKey(typed_value.val.toIntern()).err.name; | 1087 | const err_name = zcu.intern_pool.indexToKey(val.toIntern()).err.name; |
| 1146 | const error_index = zcu.global_error_set.getIndex(err_name).?; | 1088 | const error_index = zcu.global_error_set.getIndex(err_name).?; |
| 1147 | return GenResult.mcv(.{ .immediate = error_index }); | 1089 | return GenResult.mcv(.{ .immediate = error_index }); |
| 1148 | }, | 1090 | }, |
| 1149 | .ErrorUnion => { | 1091 | .ErrorUnion => { |
| 1150 | const err_type = typed_value.ty.errorUnionSet(zcu); | 1092 | const err_type = ty.errorUnionSet(zcu); |
| 1151 | const payload_type = typed_value.ty.errorUnionPayload(zcu); | 1093 | const payload_type = ty.errorUnionPayload(zcu); |
| 1152 | if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) { | 1094 | if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) { |
| 1153 | // We use the error type directly as the type. | 1095 | // We use the error type directly as the type. |
| 1154 | const err_int_ty = try zcu.errorIntType(); | 1096 | const err_int_ty = try zcu.errorIntType(); |
| 1155 | switch (zcu.intern_pool.indexToKey(typed_value.val.toIntern()).error_union.val) { | 1097 | switch (zcu.intern_pool.indexToKey(val.toIntern()).error_union.val) { |
| 1156 | .err_name => |err_name| return genTypedValue(lf, src_loc, .{ | 1098 | .err_name => |err_name| return genTypedValue( |
| 1157 | .ty = err_type, | 1099 | lf, |
| 1158 | .val = Value.fromInterned((try zcu.intern(.{ .err = .{ | 1100 | src_loc, |
| 1101 | Value.fromInterned(try zcu.intern(.{ .err = .{ | ||
| 1159 | .ty = err_type.toIntern(), | 1102 | .ty = err_type.toIntern(), |
| 1160 | .name = err_name, | 1103 | .name = err_name, |
| 1161 | } }))), | 1104 | } })), |
| 1162 | }, owner_decl_index), | 1105 | owner_decl_index, |
| 1163 | .payload => return genTypedValue(lf, src_loc, .{ | 1106 | ), |
| 1164 | .ty = err_int_ty, | 1107 | .payload => return genTypedValue( |
| 1165 | .val = try zcu.intValue(err_int_ty, 0), | 1108 | lf, |
| 1166 | }, owner_decl_index), | 1109 | src_loc, |
| 1110 | try zcu.intValue(err_int_ty, 0), | ||
| 1111 | owner_decl_index, | ||
| 1112 | ), | ||
| 1167 | } | 1113 | } |
| 1168 | } | 1114 | } |
| 1169 | }, | 1115 | }, |
| ... | @@ -1180,7 +1126,7 @@ pub fn genTypedValue( | ... | @@ -1180,7 +1126,7 @@ pub fn genTypedValue( |
| 1180 | else => {}, | 1126 | else => {}, |
| 1181 | } | 1127 | } |
| 1182 | 1128 | ||
| 1183 | return genUnnamedConst(lf, src_loc, typed_value, owner_decl_index); | 1129 | return genUnnamedConst(lf, src_loc, val, owner_decl_index); |
| 1184 | } | 1130 | } |
| 1185 | 1131 | ||
| 1186 | pub fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) u64 { | 1132 | pub fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) u64 { |
src/codegen/c.zig+37-44| ... | @@ -9,7 +9,6 @@ const Module = @import("../Module.zig"); | ... | @@ -9,7 +9,6 @@ const Module = @import("../Module.zig"); |
| 9 | const Compilation = @import("../Compilation.zig"); | 9 | const Compilation = @import("../Compilation.zig"); |
| 10 | const Value = @import("../Value.zig"); | 10 | const Value = @import("../Value.zig"); |
| 11 | const Type = @import("../type.zig").Type; | 11 | const Type = @import("../type.zig").Type; |
| 12 | const TypedValue = @import("../TypedValue.zig"); | ||
| 13 | const C = link.File.C; | 12 | const C = link.File.C; |
| 14 | const Decl = Module.Decl; | 13 | const Decl = Module.Decl; |
| 15 | const trace = @import("../tracy.zig").trace; | 14 | const trace = @import("../tracy.zig").trace; |
| ... | @@ -657,7 +656,7 @@ pub const DeclGen = struct { | ... | @@ -657,7 +656,7 @@ pub const DeclGen = struct { |
| 657 | assert(decl.has_tv); | 656 | assert(decl.has_tv); |
| 658 | 657 | ||
| 659 | // Render an undefined pointer if we have a pointer to a zero-bit or comptime type. | 658 | // Render an undefined pointer if we have a pointer to a zero-bit or comptime type. |
| 660 | if (ty.isPtrAtRuntime(mod) and !decl.ty.isFnOrHasRuntimeBits(mod)) { | 659 | if (ty.isPtrAtRuntime(mod) and !decl.typeOf(mod).isFnOrHasRuntimeBits(mod)) { |
| 661 | return dg.writeCValue(writer, .{ .undef = ty }); | 660 | return dg.writeCValue(writer, .{ .undef = ty }); |
| 662 | } | 661 | } |
| 663 | 662 | ||
| ... | @@ -673,7 +672,7 @@ pub const DeclGen = struct { | ... | @@ -673,7 +672,7 @@ pub const DeclGen = struct { |
| 673 | // them). The analysis until now should ensure that the C function | 672 | // them). The analysis until now should ensure that the C function |
| 674 | // pointers are compatible. If they are not, then there is a bug | 673 | // pointers are compatible. If they are not, then there is a bug |
| 675 | // somewhere and we should let the C compiler tell us about it. | 674 | // somewhere and we should let the C compiler tell us about it. |
| 676 | const need_typecast = if (ty.castPtrToFn(mod)) |_| false else !ty.childType(mod).eql(decl.ty, mod); | 675 | const need_typecast = if (ty.castPtrToFn(mod)) |_| false else !ty.childType(mod).eql(decl.typeOf(mod), mod); |
| 677 | if (need_typecast) { | 676 | if (need_typecast) { |
| 678 | try writer.writeAll("(("); | 677 | try writer.writeAll("(("); |
| 679 | try dg.renderType(writer, ty); | 678 | try dg.renderType(writer, ty); |
| ... | @@ -1588,9 +1587,10 @@ pub const DeclGen = struct { | ... | @@ -1588,9 +1587,10 @@ pub const DeclGen = struct { |
| 1588 | const ip = &mod.intern_pool; | 1587 | const ip = &mod.intern_pool; |
| 1589 | 1588 | ||
| 1590 | const fn_decl = mod.declPtr(fn_decl_index); | 1589 | const fn_decl = mod.declPtr(fn_decl_index); |
| 1591 | const fn_cty_idx = try dg.typeToIndex(fn_decl.ty, kind); | 1590 | const fn_ty = fn_decl.typeOf(mod); |
| 1591 | const fn_cty_idx = try dg.typeToIndex(fn_ty, kind); | ||
| 1592 | 1592 | ||
| 1593 | const fn_info = mod.typeToFunc(fn_decl.ty).?; | 1593 | const fn_info = mod.typeToFunc(fn_ty).?; |
| 1594 | if (fn_info.cc == .Naked) { | 1594 | if (fn_info.cc == .Naked) { |
| 1595 | switch (kind) { | 1595 | switch (kind) { |
| 1596 | .forward => try w.writeAll("zig_naked_decl "), | 1596 | .forward => try w.writeAll("zig_naked_decl "), |
| ... | @@ -1876,9 +1876,9 @@ pub const DeclGen = struct { | ... | @@ -1876,9 +1876,9 @@ pub const DeclGen = struct { |
| 1876 | try renderTypeSuffix(dg.pass, store.*, mod, w, cty_idx, .suffix, .{}); | 1876 | try renderTypeSuffix(dg.pass, store.*, mod, w, cty_idx, .suffix, .{}); |
| 1877 | } | 1877 | } |
| 1878 | 1878 | ||
| 1879 | fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool { | 1879 | fn declIsGlobal(dg: *DeclGen, val: Value) bool { |
| 1880 | const mod = dg.module; | 1880 | const mod = dg.module; |
| 1881 | return switch (mod.intern_pool.indexToKey(tv.val.ip_index)) { | 1881 | return switch (mod.intern_pool.indexToKey(val.ip_index)) { |
| 1882 | .variable => |variable| mod.decl_exports.contains(variable.decl), | 1882 | .variable => |variable| mod.decl_exports.contains(variable.decl), |
| 1883 | .extern_func => true, | 1883 | .extern_func => true, |
| 1884 | .func => |func| mod.decl_exports.contains(func.owner_decl), | 1884 | .func => |func| mod.decl_exports.contains(func.owner_decl), |
| ... | @@ -1971,7 +1971,7 @@ pub const DeclGen = struct { | ... | @@ -1971,7 +1971,7 @@ pub const DeclGen = struct { |
| 1971 | ) !void { | 1971 | ) !void { |
| 1972 | const decl = dg.module.declPtr(decl_index); | 1972 | const decl = dg.module.declPtr(decl_index); |
| 1973 | const fwd = dg.fwdDeclWriter(); | 1973 | const fwd = dg.fwdDeclWriter(); |
| 1974 | const is_global = variable.is_extern or dg.declIsGlobal(.{ .ty = decl.ty, .val = decl.val }); | 1974 | const is_global = variable.is_extern or dg.declIsGlobal(decl.val); |
| 1975 | try fwd.writeAll(if (is_global) "zig_extern " else "static "); | 1975 | try fwd.writeAll(if (is_global) "zig_extern " else "static "); |
| 1976 | const maybe_exports = dg.module.decl_exports.get(decl_index); | 1976 | const maybe_exports = dg.module.decl_exports.get(decl_index); |
| 1977 | const export_weak_linkage = if (maybe_exports) |exports| | 1977 | const export_weak_linkage = if (maybe_exports) |exports| |
| ... | @@ -1982,7 +1982,7 @@ pub const DeclGen = struct { | ... | @@ -1982,7 +1982,7 @@ pub const DeclGen = struct { |
| 1982 | if (variable.is_threadlocal) try fwd.writeAll("zig_threadlocal "); | 1982 | if (variable.is_threadlocal) try fwd.writeAll("zig_threadlocal "); |
| 1983 | try dg.renderTypeAndName( | 1983 | try dg.renderTypeAndName( |
| 1984 | fwd, | 1984 | fwd, |
| 1985 | decl.ty, | 1985 | decl.typeOf(dg.module), |
| 1986 | .{ .decl = decl_index }, | 1986 | .{ .decl = decl_index }, |
| 1987 | CQualifiers.init(.{ .@"const" = variable.is_const }), | 1987 | CQualifiers.init(.{ .@"const" = variable.is_const }), |
| 1988 | decl.alignment, | 1988 | decl.alignment, |
| ... | @@ -2009,7 +2009,6 @@ pub const DeclGen = struct { | ... | @@ -2009,7 +2009,6 @@ pub const DeclGen = struct { |
| 2009 | fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: InternPool.DeclIndex, export_index: u32) !void { | 2009 | fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: InternPool.DeclIndex, export_index: u32) !void { |
| 2010 | const mod = dg.module; | 2010 | const mod = dg.module; |
| 2011 | const decl = mod.declPtr(decl_index); | 2011 | const decl = mod.declPtr(decl_index); |
| 2012 | try mod.markDeclAlive(decl); | ||
| 2013 | 2012 | ||
| 2014 | if (mod.decl_exports.get(decl_index)) |exports| { | 2013 | if (mod.decl_exports.get(decl_index)) |exports| { |
| 2015 | try writer.print("{ }", .{ | 2014 | try writer.print("{ }", .{ |
| ... | @@ -2656,13 +2655,12 @@ fn genExports(o: *Object) !void { | ... | @@ -2656,13 +2655,12 @@ fn genExports(o: *Object) !void { |
| 2656 | .anon, .flush => return, | 2655 | .anon, .flush => return, |
| 2657 | }; | 2656 | }; |
| 2658 | const decl = mod.declPtr(decl_index); | 2657 | const decl = mod.declPtr(decl_index); |
| 2659 | const tv: TypedValue = .{ .ty = decl.ty, .val = Value.fromInterned((try decl.internValue(mod))) }; | ||
| 2660 | const fwd = o.dg.fwdDeclWriter(); | 2658 | const fwd = o.dg.fwdDeclWriter(); |
| 2661 | 2659 | ||
| 2662 | const exports = mod.decl_exports.get(decl_index) orelse return; | 2660 | const exports = mod.decl_exports.get(decl_index) orelse return; |
| 2663 | if (exports.items.len < 2) return; | 2661 | if (exports.items.len < 2) return; |
| 2664 | 2662 | ||
| 2665 | const is_variable_const = switch (ip.indexToKey(tv.val.toIntern())) { | 2663 | const is_variable_const = switch (ip.indexToKey(decl.val.toIntern())) { |
| 2666 | .func => return for (exports.items[1..], 1..) |@"export", i| { | 2664 | .func => return for (exports.items[1..], 1..) |@"export", i| { |
| 2667 | try fwd.writeAll("zig_extern "); | 2665 | try fwd.writeAll("zig_extern "); |
| 2668 | if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage_fn "); | 2666 | if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage_fn "); |
| ... | @@ -2687,7 +2685,7 @@ fn genExports(o: *Object) !void { | ... | @@ -2687,7 +2685,7 @@ fn genExports(o: *Object) !void { |
| 2687 | const export_name = ip.stringToSlice(@"export".opts.name); | 2685 | const export_name = ip.stringToSlice(@"export".opts.name); |
| 2688 | try o.dg.renderTypeAndName( | 2686 | try o.dg.renderTypeAndName( |
| 2689 | fwd, | 2687 | fwd, |
| 2690 | decl.ty, | 2688 | decl.typeOf(mod), |
| 2691 | .{ .identifier = export_name }, | 2689 | .{ .identifier = export_name }, |
| 2692 | CQualifiers.init(.{ .@"const" = is_variable_const }), | 2690 | CQualifiers.init(.{ .@"const" = is_variable_const }), |
| 2693 | decl.alignment, | 2691 | decl.alignment, |
| ... | @@ -2769,7 +2767,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void { | ... | @@ -2769,7 +2767,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void { |
| 2769 | }, | 2767 | }, |
| 2770 | .never_tail, .never_inline => |fn_decl_index| { | 2768 | .never_tail, .never_inline => |fn_decl_index| { |
| 2771 | const fn_decl = mod.declPtr(fn_decl_index); | 2769 | const fn_decl = mod.declPtr(fn_decl_index); |
| 2772 | const fn_cty = try o.dg.typeToCType(fn_decl.ty, .complete); | 2770 | const fn_cty = try o.dg.typeToCType(fn_decl.typeOf(mod), .complete); |
| 2773 | const fn_info = fn_cty.cast(CType.Payload.Function).?.data; | 2771 | const fn_info = fn_cty.cast(CType.Payload.Function).?.data; |
| 2774 | 2772 | ||
| 2775 | const fwd_decl_writer = o.dg.fwdDeclWriter(); | 2773 | const fwd_decl_writer = o.dg.fwdDeclWriter(); |
| ... | @@ -2805,15 +2803,11 @@ pub fn genFunc(f: *Function) !void { | ... | @@ -2805,15 +2803,11 @@ pub fn genFunc(f: *Function) !void { |
| 2805 | const gpa = o.dg.gpa; | 2803 | const gpa = o.dg.gpa; |
| 2806 | const decl_index = o.dg.pass.decl; | 2804 | const decl_index = o.dg.pass.decl; |
| 2807 | const decl = mod.declPtr(decl_index); | 2805 | const decl = mod.declPtr(decl_index); |
| 2808 | const tv: TypedValue = .{ | ||
| 2809 | .ty = decl.ty, | ||
| 2810 | .val = decl.val, | ||
| 2811 | }; | ||
| 2812 | 2806 | ||
| 2813 | o.code_header = std.ArrayList(u8).init(gpa); | 2807 | o.code_header = std.ArrayList(u8).init(gpa); |
| 2814 | defer o.code_header.deinit(); | 2808 | defer o.code_header.deinit(); |
| 2815 | 2809 | ||
| 2816 | const is_global = o.dg.declIsGlobal(tv); | 2810 | const is_global = o.dg.declIsGlobal(decl.val); |
| 2817 | const fwd_decl_writer = o.dg.fwdDeclWriter(); | 2811 | const fwd_decl_writer = o.dg.fwdDeclWriter(); |
| 2818 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); | 2812 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); |
| 2819 | 2813 | ||
| ... | @@ -2893,22 +2887,23 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -2893,22 +2887,23 @@ pub fn genDecl(o: *Object) !void { |
| 2893 | const mod = o.dg.module; | 2887 | const mod = o.dg.module; |
| 2894 | const decl_index = o.dg.pass.decl; | 2888 | const decl_index = o.dg.pass.decl; |
| 2895 | const decl = mod.declPtr(decl_index); | 2889 | const decl = mod.declPtr(decl_index); |
| 2896 | const tv: TypedValue = .{ .ty = decl.ty, .val = Value.fromInterned((try decl.internValue(mod))) }; | 2890 | const decl_val = decl.val; |
| 2891 | const decl_ty = decl_val.typeOf(mod); | ||
| 2897 | 2892 | ||
| 2898 | if (!tv.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return; | 2893 | if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return; |
| 2899 | if (tv.val.getExternFunc(mod)) |_| { | 2894 | if (decl_val.getExternFunc(mod)) |_| { |
| 2900 | const fwd_decl_writer = o.dg.fwdDeclWriter(); | 2895 | const fwd_decl_writer = o.dg.fwdDeclWriter(); |
| 2901 | try fwd_decl_writer.writeAll("zig_extern "); | 2896 | try fwd_decl_writer.writeAll("zig_extern "); |
| 2902 | try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 }); | 2897 | try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 }); |
| 2903 | try fwd_decl_writer.writeAll(";\n"); | 2898 | try fwd_decl_writer.writeAll(";\n"); |
| 2904 | try genExports(o); | 2899 | try genExports(o); |
| 2905 | } else if (tv.val.getVariable(mod)) |variable| { | 2900 | } else if (decl_val.getVariable(mod)) |variable| { |
| 2906 | try o.dg.renderFwdDecl(decl_index, variable, .final); | 2901 | try o.dg.renderFwdDecl(decl_index, variable, .final); |
| 2907 | try genExports(o); | 2902 | try genExports(o); |
| 2908 | 2903 | ||
| 2909 | if (variable.is_extern) return; | 2904 | if (variable.is_extern) return; |
| 2910 | 2905 | ||
| 2911 | const is_global = variable.is_extern or o.dg.declIsGlobal(tv); | 2906 | const is_global = variable.is_extern or o.dg.declIsGlobal(decl_val); |
| 2912 | const w = o.writer(); | 2907 | const w = o.writer(); |
| 2913 | if (!is_global) try w.writeAll("static "); | 2908 | if (!is_global) try w.writeAll("static "); |
| 2914 | if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage "); | 2909 | if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage "); |
| ... | @@ -2916,22 +2911,22 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -2916,22 +2911,22 @@ pub fn genDecl(o: *Object) !void { |
| 2916 | if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| | 2911 | if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| |
| 2917 | try w.print("zig_linksection(\"{s}\", ", .{s}); | 2912 | try w.print("zig_linksection(\"{s}\", ", .{s}); |
| 2918 | const decl_c_value = .{ .decl = decl_index }; | 2913 | const decl_c_value = .{ .decl = decl_index }; |
| 2919 | try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .{}, decl.alignment, .complete); | 2914 | try o.dg.renderTypeAndName(w, decl_ty, decl_c_value, .{}, decl.alignment, .complete); |
| 2920 | if (decl.@"linksection" != .none) try w.writeAll(", read, write)"); | 2915 | if (decl.@"linksection" != .none) try w.writeAll(", read, write)"); |
| 2921 | try w.writeAll(" = "); | 2916 | try w.writeAll(" = "); |
| 2922 | try o.dg.renderValue(w, tv.ty, Value.fromInterned(variable.init), .StaticInitializer); | 2917 | try o.dg.renderValue(w, decl_ty, Value.fromInterned(variable.init), .StaticInitializer); |
| 2923 | try w.writeByte(';'); | 2918 | try w.writeByte(';'); |
| 2924 | try o.indent_writer.insertNewline(); | 2919 | try o.indent_writer.insertNewline(); |
| 2925 | } else { | 2920 | } else { |
| 2926 | const is_global = o.dg.module.decl_exports.contains(decl_index); | 2921 | const is_global = o.dg.module.decl_exports.contains(decl_index); |
| 2927 | const decl_c_value = .{ .decl = decl_index }; | 2922 | const decl_c_value = .{ .decl = decl_index }; |
| 2928 | try genDeclValue(o, tv, is_global, decl_c_value, decl.alignment, decl.@"linksection"); | 2923 | try genDeclValue(o, decl_val, is_global, decl_c_value, decl.alignment, decl.@"linksection"); |
| 2929 | } | 2924 | } |
| 2930 | } | 2925 | } |
| 2931 | 2926 | ||
| 2932 | pub fn genDeclValue( | 2927 | pub fn genDeclValue( |
| 2933 | o: *Object, | 2928 | o: *Object, |
| 2934 | tv: TypedValue, | 2929 | val: Value, |
| 2935 | is_global: bool, | 2930 | is_global: bool, |
| 2936 | decl_c_value: CValue, | 2931 | decl_c_value: CValue, |
| 2937 | alignment: Alignment, | 2932 | alignment: Alignment, |
| ... | @@ -2940,8 +2935,10 @@ pub fn genDeclValue( | ... | @@ -2940,8 +2935,10 @@ pub fn genDeclValue( |
| 2940 | const mod = o.dg.module; | 2935 | const mod = o.dg.module; |
| 2941 | const fwd_decl_writer = o.dg.fwdDeclWriter(); | 2936 | const fwd_decl_writer = o.dg.fwdDeclWriter(); |
| 2942 | 2937 | ||
| 2938 | const ty = val.typeOf(mod); | ||
| 2939 | |||
| 2943 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); | 2940 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); |
| 2944 | try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete); | 2941 | try o.dg.renderTypeAndName(fwd_decl_writer, ty, decl_c_value, Const, alignment, .complete); |
| 2945 | switch (o.dg.pass) { | 2942 | switch (o.dg.pass) { |
| 2946 | .decl => |decl_index| { | 2943 | .decl => |decl_index| { |
| 2947 | if (mod.decl_exports.get(decl_index)) |exports| { | 2944 | if (mod.decl_exports.get(decl_index)) |exports| { |
| ... | @@ -2964,10 +2961,10 @@ pub fn genDeclValue( | ... | @@ -2964,10 +2961,10 @@ pub fn genDeclValue( |
| 2964 | 2961 | ||
| 2965 | if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s| | 2962 | if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s| |
| 2966 | try w.print("zig_linksection(\"{s}\", ", .{s}); | 2963 | try w.print("zig_linksection(\"{s}\", ", .{s}); |
| 2967 | try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, alignment, .complete); | 2964 | try o.dg.renderTypeAndName(w, ty, decl_c_value, Const, alignment, .complete); |
| 2968 | if (link_section != .none) try w.writeAll(", read)"); | 2965 | if (link_section != .none) try w.writeAll(", read)"); |
| 2969 | try w.writeAll(" = "); | 2966 | try w.writeAll(" = "); |
| 2970 | try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer); | 2967 | try o.dg.renderValue(w, ty, val, .StaticInitializer); |
| 2971 | try w.writeAll(";\n"); | 2968 | try w.writeAll(";\n"); |
| 2972 | } | 2969 | } |
| 2973 | 2970 | ||
| ... | @@ -2978,14 +2975,10 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void { | ... | @@ -2978,14 +2975,10 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void { |
| 2978 | const mod = dg.module; | 2975 | const mod = dg.module; |
| 2979 | const decl_index = dg.pass.decl; | 2976 | const decl_index = dg.pass.decl; |
| 2980 | const decl = mod.declPtr(decl_index); | 2977 | const decl = mod.declPtr(decl_index); |
| 2981 | const tv: TypedValue = .{ | ||
| 2982 | .ty = decl.ty, | ||
| 2983 | .val = decl.val, | ||
| 2984 | }; | ||
| 2985 | const writer = dg.fwdDeclWriter(); | 2978 | const writer = dg.fwdDeclWriter(); |
| 2986 | 2979 | ||
| 2987 | switch (tv.ty.zigTypeTag(mod)) { | 2980 | switch (decl.val.typeOf(mod).zigTypeTag(mod)) { |
| 2988 | .Fn => if (dg.declIsGlobal(tv)) { | 2981 | .Fn => if (dg.declIsGlobal(decl.val)) { |
| 2989 | try writer.writeAll("zig_extern "); | 2982 | try writer.writeAll("zig_extern "); |
| 2990 | try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 }); | 2983 | try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 }); |
| 2991 | try dg.fwd_decl.appendSlice(";\n"); | 2984 | try dg.fwd_decl.appendSlice(";\n"); |
| ... | @@ -5304,25 +5297,25 @@ fn airIsNull( | ... | @@ -5304,25 +5297,25 @@ fn airIsNull( |
| 5304 | const err_int_ty = try mod.errorIntType(); | 5297 | const err_int_ty = try mod.errorIntType(); |
| 5305 | 5298 | ||
| 5306 | const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) | 5299 | const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) |
| 5307 | TypedValue{ .ty = Type.bool, .val = Value.true } | 5300 | Value.true |
| 5308 | else if (optional_ty.isPtrLikeOptional(mod)) | 5301 | else if (optional_ty.isPtrLikeOptional(mod)) |
| 5309 | // operand is a regular pointer, test `operand !=/== NULL` | 5302 | // operand is a regular pointer, test `operand !=/== NULL` |
| 5310 | TypedValue{ .ty = optional_ty, .val = try mod.getCoerced(Value.null, optional_ty) } | 5303 | try mod.getCoerced(Value.null, optional_ty) |
| 5311 | else if (payload_ty.zigTypeTag(mod) == .ErrorSet) | 5304 | else if (payload_ty.zigTypeTag(mod) == .ErrorSet) |
| 5312 | TypedValue{ .ty = err_int_ty, .val = try mod.intValue(err_int_ty, 0) } | 5305 | try mod.intValue(err_int_ty, 0) |
| 5313 | else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: { | 5306 | else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: { |
| 5314 | try writer.writeAll(".ptr"); | 5307 | try writer.writeAll(".ptr"); |
| 5315 | const slice_ptr_ty = payload_ty.slicePtrFieldType(mod); | 5308 | const slice_ptr_ty = payload_ty.slicePtrFieldType(mod); |
| 5316 | const opt_slice_ptr_ty = try mod.optionalType(slice_ptr_ty.toIntern()); | 5309 | const opt_slice_ptr_ty = try mod.optionalType(slice_ptr_ty.toIntern()); |
| 5317 | break :rhs TypedValue{ .ty = opt_slice_ptr_ty, .val = try mod.nullValue(opt_slice_ptr_ty) }; | 5310 | break :rhs try mod.nullValue(opt_slice_ptr_ty); |
| 5318 | } else rhs: { | 5311 | } else rhs: { |
| 5319 | try writer.writeAll(".is_null"); | 5312 | try writer.writeAll(".is_null"); |
| 5320 | break :rhs TypedValue{ .ty = Type.bool, .val = Value.true }; | 5313 | break :rhs Value.true; |
| 5321 | }; | 5314 | }; |
| 5322 | try writer.writeByte(' '); | 5315 | try writer.writeByte(' '); |
| 5323 | try writer.writeAll(operator); | 5316 | try writer.writeAll(operator); |
| 5324 | try writer.writeByte(' '); | 5317 | try writer.writeByte(' '); |
| 5325 | try f.object.dg.renderValue(writer, rhs.ty, rhs.val, .Other); | 5318 | try f.object.dg.renderValue(writer, rhs.typeOf(mod), rhs, .Other); |
| 5326 | try writer.writeAll(";\n"); | 5319 | try writer.writeAll(";\n"); |
| 5327 | return local; | 5320 | return local; |
| 5328 | } | 5321 | } |
| ... | @@ -7392,7 +7385,7 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -7392,7 +7385,7 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue { |
| 7392 | const inst_ty = f.typeOfIndex(inst); | 7385 | const inst_ty = f.typeOfIndex(inst); |
| 7393 | const decl_index = f.object.dg.pass.decl; | 7386 | const decl_index = f.object.dg.pass.decl; |
| 7394 | const decl = mod.declPtr(decl_index); | 7387 | const decl = mod.declPtr(decl_index); |
| 7395 | const fn_cty = try f.typeToCType(decl.ty, .complete); | 7388 | const fn_cty = try f.typeToCType(decl.typeOf(mod), .complete); |
| 7396 | const param_len = fn_cty.castTag(.varargs_function).?.data.param_types.len; | 7389 | const param_len = fn_cty.castTag(.varargs_function).?.data.param_types.len; |
| 7397 | 7390 | ||
| 7398 | const writer = f.object.writer(); | 7391 | const writer = f.object.writer(); |
src/codegen/llvm.zig+27-40| ... | @@ -18,7 +18,6 @@ const Module = @import("../Module.zig"); | ... | @@ -18,7 +18,6 @@ const Module = @import("../Module.zig"); |
| 18 | const Zcu = Module; | 18 | const Zcu = Module; |
| 19 | const InternPool = @import("../InternPool.zig"); | 19 | const InternPool = @import("../InternPool.zig"); |
| 20 | const Package = @import("../Package.zig"); | 20 | const Package = @import("../Package.zig"); |
| 21 | const TypedValue = @import("../TypedValue.zig"); | ||
| 22 | const Air = @import("../Air.zig"); | 21 | const Air = @import("../Air.zig"); |
| 23 | const Liveness = @import("../Liveness.zig"); | 22 | const Liveness = @import("../Liveness.zig"); |
| 24 | const Value = @import("../Value.zig"); | 23 | const Value = @import("../Value.zig"); |
| ... | @@ -1384,7 +1383,7 @@ pub const Object = struct { | ... | @@ -1384,7 +1383,7 @@ pub const Object = struct { |
| 1384 | const decl = zcu.declPtr(decl_index); | 1383 | const decl = zcu.declPtr(decl_index); |
| 1385 | const namespace = zcu.namespacePtr(decl.src_namespace); | 1384 | const namespace = zcu.namespacePtr(decl.src_namespace); |
| 1386 | const owner_mod = namespace.file_scope.mod; | 1385 | const owner_mod = namespace.file_scope.mod; |
| 1387 | const fn_info = zcu.typeToFunc(decl.ty).?; | 1386 | const fn_info = zcu.typeToFunc(decl.typeOf(zcu)).?; |
| 1388 | const target = zcu.getTarget(); | 1387 | const target = zcu.getTarget(); |
| 1389 | const ip = &zcu.intern_pool; | 1388 | const ip = &zcu.intern_pool; |
| 1390 | 1389 | ||
| ... | @@ -1659,7 +1658,7 @@ pub const Object = struct { | ... | @@ -1659,7 +1658,7 @@ pub const Object = struct { |
| 1659 | const line_number = decl.src_line + 1; | 1658 | const line_number = decl.src_line + 1; |
| 1660 | const is_internal_linkage = decl.val.getExternFunc(zcu) == null and | 1659 | const is_internal_linkage = decl.val.getExternFunc(zcu) == null and |
| 1661 | !zcu.decl_exports.contains(decl_index); | 1660 | !zcu.decl_exports.contains(decl_index); |
| 1662 | const debug_decl_type = try o.lowerDebugType(decl.ty); | 1661 | const debug_decl_type = try o.lowerDebugType(decl.typeOf(zcu)); |
| 1663 | 1662 | ||
| 1664 | const subprogram = try o.builder.debugSubprogram( | 1663 | const subprogram = try o.builder.debugSubprogram( |
| 1665 | file, | 1664 | file, |
| ... | @@ -1762,7 +1761,7 @@ pub const Object = struct { | ... | @@ -1762,7 +1761,7 @@ pub const Object = struct { |
| 1762 | const decl_name = decl_name: { | 1761 | const decl_name = decl_name: { |
| 1763 | const decl_name = mod.intern_pool.stringToSlice(decl.name); | 1762 | const decl_name = mod.intern_pool.stringToSlice(decl.name); |
| 1764 | 1763 | ||
| 1765 | if (mod.getTarget().isWasm() and try decl.isFunction(mod)) { | 1764 | if (mod.getTarget().isWasm() and decl.val.typeOf(mod).zigTypeTag(mod) == .Fn) { |
| 1766 | if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| { | 1765 | if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| { |
| 1767 | if (!std.mem.eql(u8, lib_name, "c")) { | 1766 | if (!std.mem.eql(u8, lib_name, "c")) { |
| 1768 | break :decl_name try self.builder.strtabStringFmt("{s}|{s}", .{ decl_name, lib_name }); | 1767 | break :decl_name try self.builder.strtabStringFmt("{s}|{s}", .{ decl_name, lib_name }); |
| ... | @@ -2881,7 +2880,7 @@ pub const Object = struct { | ... | @@ -2881,7 +2880,7 @@ pub const Object = struct { |
| 2881 | const decl = zcu.declPtr(decl_index); | 2880 | const decl = zcu.declPtr(decl_index); |
| 2882 | const namespace = zcu.namespacePtr(decl.src_namespace); | 2881 | const namespace = zcu.namespacePtr(decl.src_namespace); |
| 2883 | const owner_mod = namespace.file_scope.mod; | 2882 | const owner_mod = namespace.file_scope.mod; |
| 2884 | const zig_fn_type = decl.ty; | 2883 | const zig_fn_type = decl.typeOf(zcu); |
| 2885 | const gop = try o.decl_map.getOrPut(gpa, decl_index); | 2884 | const gop = try o.decl_map.getOrPut(gpa, decl_index); |
| 2886 | if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function; | 2885 | if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function; |
| 2887 | 2886 | ||
| ... | @@ -3112,7 +3111,7 @@ pub const Object = struct { | ... | @@ -3112,7 +3111,7 @@ pub const Object = struct { |
| 3112 | try o.builder.strtabString(mod.intern_pool.stringToSlice( | 3111 | try o.builder.strtabString(mod.intern_pool.stringToSlice( |
| 3113 | if (is_extern) decl.name else try decl.fullyQualifiedName(mod), | 3112 | if (is_extern) decl.name else try decl.fullyQualifiedName(mod), |
| 3114 | )), | 3113 | )), |
| 3115 | try o.lowerType(decl.ty), | 3114 | try o.lowerType(decl.typeOf(mod)), |
| 3116 | toLlvmGlobalAddressSpace(decl.@"addrspace", mod.getTarget()), | 3115 | toLlvmGlobalAddressSpace(decl.@"addrspace", mod.getTarget()), |
| 3117 | ); | 3116 | ); |
| 3118 | gop.value_ptr.* = variable_index.ptrConst(&o.builder).global; | 3117 | gop.value_ptr.* = variable_index.ptrConst(&o.builder).global; |
| ... | @@ -3722,15 +3721,11 @@ pub const Object = struct { | ... | @@ -3722,15 +3721,11 @@ pub const Object = struct { |
| 3722 | => unreachable, // non-runtime values | 3721 | => unreachable, // non-runtime values |
| 3723 | .extern_func => |extern_func| { | 3722 | .extern_func => |extern_func| { |
| 3724 | const fn_decl_index = extern_func.decl; | 3723 | const fn_decl_index = extern_func.decl; |
| 3725 | const fn_decl = mod.declPtr(fn_decl_index); | ||
| 3726 | try mod.markDeclAlive(fn_decl); | ||
| 3727 | const function_index = try o.resolveLlvmFunction(fn_decl_index); | 3724 | const function_index = try o.resolveLlvmFunction(fn_decl_index); |
| 3728 | return function_index.ptrConst(&o.builder).global.toConst(); | 3725 | return function_index.ptrConst(&o.builder).global.toConst(); |
| 3729 | }, | 3726 | }, |
| 3730 | .func => |func| { | 3727 | .func => |func| { |
| 3731 | const fn_decl_index = func.owner_decl; | 3728 | const fn_decl_index = func.owner_decl; |
| 3732 | const fn_decl = mod.declPtr(fn_decl_index); | ||
| 3733 | try mod.markDeclAlive(fn_decl); | ||
| 3734 | const function_index = try o.resolveLlvmFunction(fn_decl_index); | 3729 | const function_index = try o.resolveLlvmFunction(fn_decl_index); |
| 3735 | return function_index.ptrConst(&o.builder).global.toConst(); | 3730 | return function_index.ptrConst(&o.builder).global.toConst(); |
| 3736 | }, | 3731 | }, |
| ... | @@ -4262,8 +4257,7 @@ pub const Object = struct { | ... | @@ -4262,8 +4257,7 @@ pub const Object = struct { |
| 4262 | fn lowerParentPtrDecl(o: *Object, decl_index: InternPool.DeclIndex) Allocator.Error!Builder.Constant { | 4257 | fn lowerParentPtrDecl(o: *Object, decl_index: InternPool.DeclIndex) Allocator.Error!Builder.Constant { |
| 4263 | const mod = o.module; | 4258 | const mod = o.module; |
| 4264 | const decl = mod.declPtr(decl_index); | 4259 | const decl = mod.declPtr(decl_index); |
| 4265 | try mod.markDeclAlive(decl); | 4260 | const ptr_ty = try mod.singleMutPtrType(decl.typeOf(mod)); |
| 4266 | const ptr_ty = try mod.singleMutPtrType(decl.ty); | ||
| 4267 | return o.lowerDeclRefValue(ptr_ty, decl_index); | 4261 | return o.lowerDeclRefValue(ptr_ty, decl_index); |
| 4268 | } | 4262 | } |
| 4269 | 4263 | ||
| ... | @@ -4450,11 +4444,10 @@ pub const Object = struct { | ... | @@ -4450,11 +4444,10 @@ pub const Object = struct { |
| 4450 | } | 4444 | } |
| 4451 | } | 4445 | } |
| 4452 | 4446 | ||
| 4453 | const is_fn_body = decl.ty.zigTypeTag(mod) == .Fn; | 4447 | const decl_ty = decl.typeOf(mod); |
| 4454 | if ((!is_fn_body and !decl.ty.hasRuntimeBits(mod)) or | 4448 | const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn; |
| 4455 | (is_fn_body and mod.typeToFunc(decl.ty).?.is_generic)) return o.lowerPtrToVoid(ty); | 4449 | if ((!is_fn_body and !decl_ty.hasRuntimeBits(mod)) or |
| 4456 | 4450 | (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic)) return o.lowerPtrToVoid(ty); | |
| 4457 | try mod.markDeclAlive(decl); | ||
| 4458 | 4451 | ||
| 4459 | const llvm_global = if (is_fn_body) | 4452 | const llvm_global = if (is_fn_body) |
| 4460 | (try o.resolveLlvmFunction(decl_index)).ptrConst(&o.builder).global | 4453 | (try o.resolveLlvmFunction(decl_index)).ptrConst(&o.builder).global |
| ... | @@ -4740,7 +4733,7 @@ pub const DeclGen = struct { | ... | @@ -4740,7 +4733,7 @@ pub const DeclGen = struct { |
| 4740 | debug_file, // File | 4733 | debug_file, // File |
| 4741 | debug_file, // Scope | 4734 | debug_file, // Scope |
| 4742 | line_number, | 4735 | line_number, |
| 4743 | try o.lowerDebugType(decl.ty), | 4736 | try o.lowerDebugType(decl.typeOf(zcu)), |
| 4744 | variable_index, | 4737 | variable_index, |
| 4745 | .{ .local = is_internal_linkage }, | 4738 | .{ .local = is_internal_linkage }, |
| 4746 | ); | 4739 | ); |
| ... | @@ -4829,19 +4822,17 @@ pub const FuncGen = struct { | ... | @@ -4829,19 +4822,17 @@ pub const FuncGen = struct { |
| 4829 | 4822 | ||
| 4830 | const o = self.dg.object; | 4823 | const o = self.dg.object; |
| 4831 | const mod = o.module; | 4824 | const mod = o.module; |
| 4832 | const llvm_val = try self.resolveValue(.{ | 4825 | const llvm_val = try self.resolveValue((try self.air.value(inst, mod)).?); |
| 4833 | .ty = self.typeOf(inst), | ||
| 4834 | .val = (try self.air.value(inst, mod)).?, | ||
| 4835 | }); | ||
| 4836 | gop.value_ptr.* = llvm_val.toValue(); | 4826 | gop.value_ptr.* = llvm_val.toValue(); |
| 4837 | return llvm_val.toValue(); | 4827 | return llvm_val.toValue(); |
| 4838 | } | 4828 | } |
| 4839 | 4829 | ||
| 4840 | fn resolveValue(self: *FuncGen, tv: TypedValue) Error!Builder.Constant { | 4830 | fn resolveValue(self: *FuncGen, val: Value) Error!Builder.Constant { |
| 4841 | const o = self.dg.object; | 4831 | const o = self.dg.object; |
| 4842 | const mod = o.module; | 4832 | const mod = o.module; |
| 4843 | const llvm_val = try o.lowerValue(tv.val.toIntern()); | 4833 | const ty = val.typeOf(mod); |
| 4844 | if (!isByRef(tv.ty, mod)) return llvm_val; | 4834 | const llvm_val = try o.lowerValue(val.toIntern()); |
| 4835 | if (!isByRef(ty, mod)) return llvm_val; | ||
| 4845 | 4836 | ||
| 4846 | // We have an LLVM value but we need to create a global constant and | 4837 | // We have an LLVM value but we need to create a global constant and |
| 4847 | // set the value as its initializer, and then return a pointer to the global. | 4838 | // set the value as its initializer, and then return a pointer to the global. |
| ... | @@ -4855,7 +4846,7 @@ pub const FuncGen = struct { | ... | @@ -4855,7 +4846,7 @@ pub const FuncGen = struct { |
| 4855 | variable_index.setLinkage(.private, &o.builder); | 4846 | variable_index.setLinkage(.private, &o.builder); |
| 4856 | variable_index.setMutability(.constant, &o.builder); | 4847 | variable_index.setMutability(.constant, &o.builder); |
| 4857 | variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); | 4848 | variable_index.setUnnamedAddr(.unnamed_addr, &o.builder); |
| 4858 | variable_index.setAlignment(tv.ty.abiAlignment(mod).toLlvm(), &o.builder); | 4849 | variable_index.setAlignment(ty.abiAlignment(mod).toLlvm(), &o.builder); |
| 4859 | return o.builder.convConst( | 4850 | return o.builder.convConst( |
| 4860 | .unneeded, | 4851 | .unneeded, |
| 4861 | variable_index.toConst(&o.builder), | 4852 | variable_index.toConst(&o.builder), |
| ... | @@ -4867,11 +4858,10 @@ pub const FuncGen = struct { | ... | @@ -4867,11 +4858,10 @@ pub const FuncGen = struct { |
| 4867 | const o = self.dg.object; | 4858 | const o = self.dg.object; |
| 4868 | const mod = o.module; | 4859 | const mod = o.module; |
| 4869 | if (o.null_opt_usize == .no_init) { | 4860 | if (o.null_opt_usize == .no_init) { |
| 4870 | const ty = try mod.intern(.{ .opt_type = .usize_type }); | 4861 | o.null_opt_usize = try self.resolveValue(Value.fromInterned(try mod.intern(.{ .opt = .{ |
| 4871 | o.null_opt_usize = try self.resolveValue(.{ | 4862 | .ty = try mod.intern(.{ .opt_type = .usize_type }), |
| 4872 | .ty = Type.fromInterned(ty), | 4863 | .val = .none, |
| 4873 | .val = Value.fromInterned((try mod.intern(.{ .opt = .{ .ty = ty, .val = .none } }))), | 4864 | } }))); |
| 4874 | }); | ||
| 4875 | } | 4865 | } |
| 4876 | return o.null_opt_usize; | 4866 | return o.null_opt_usize; |
| 4877 | } | 4867 | } |
| ... | @@ -5530,8 +5520,8 @@ pub const FuncGen = struct { | ... | @@ -5530,8 +5520,8 @@ pub const FuncGen = struct { |
| 5530 | const mod = o.module; | 5520 | const mod = o.module; |
| 5531 | const msg_decl_index = mod.panic_messages[@intFromEnum(panic_id)].unwrap().?; | 5521 | const msg_decl_index = mod.panic_messages[@intFromEnum(panic_id)].unwrap().?; |
| 5532 | const msg_decl = mod.declPtr(msg_decl_index); | 5522 | const msg_decl = mod.declPtr(msg_decl_index); |
| 5533 | const msg_len = msg_decl.ty.childType(mod).arrayLen(mod); | 5523 | const msg_len = msg_decl.typeOf(mod).childType(mod).arrayLen(mod); |
| 5534 | const msg_ptr = try o.lowerValue(try msg_decl.internValue(mod)); | 5524 | const msg_ptr = try o.lowerValue(msg_decl.val.toIntern()); |
| 5535 | const null_opt_addr_global = try fg.resolveNullOptUsize(); | 5525 | const null_opt_addr_global = try fg.resolveNullOptUsize(); |
| 5536 | const target = mod.getTarget(); | 5526 | const target = mod.getTarget(); |
| 5537 | const llvm_usize = try o.lowerType(Type.usize); | 5527 | const llvm_usize = try o.lowerType(Type.usize); |
| ... | @@ -5544,7 +5534,7 @@ pub const FuncGen = struct { | ... | @@ -5544,7 +5534,7 @@ pub const FuncGen = struct { |
| 5544 | // ) | 5534 | // ) |
| 5545 | const panic_func = mod.funcInfo(mod.panic_func_index); | 5535 | const panic_func = mod.funcInfo(mod.panic_func_index); |
| 5546 | const panic_decl = mod.declPtr(panic_func.owner_decl); | 5536 | const panic_decl = mod.declPtr(panic_func.owner_decl); |
| 5547 | const fn_info = mod.typeToFunc(panic_decl.ty).?; | 5537 | const fn_info = mod.typeToFunc(panic_decl.typeOf(mod)).?; |
| 5548 | const panic_global = try o.resolveLlvmFunction(panic_func.owner_decl); | 5538 | const panic_global = try o.resolveLlvmFunction(panic_func.owner_decl); |
| 5549 | _ = try fg.wip.call( | 5539 | _ = try fg.wip.call( |
| 5550 | .normal, | 5540 | .normal, |
| ... | @@ -5612,7 +5602,7 @@ pub const FuncGen = struct { | ... | @@ -5612,7 +5602,7 @@ pub const FuncGen = struct { |
| 5612 | _ = try self.wip.retVoid(); | 5602 | _ = try self.wip.retVoid(); |
| 5613 | return .none; | 5603 | return .none; |
| 5614 | } | 5604 | } |
| 5615 | const fn_info = mod.typeToFunc(self.dg.decl.ty).?; | 5605 | const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?; |
| 5616 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 5606 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 5617 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { | 5607 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { |
| 5618 | // Functions with an empty error set are emitted with an error code | 5608 | // Functions with an empty error set are emitted with an error code |
| ... | @@ -5674,7 +5664,7 @@ pub const FuncGen = struct { | ... | @@ -5674,7 +5664,7 @@ pub const FuncGen = struct { |
| 5674 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 5664 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5675 | const ptr_ty = self.typeOf(un_op); | 5665 | const ptr_ty = self.typeOf(un_op); |
| 5676 | const ret_ty = ptr_ty.childType(mod); | 5666 | const ret_ty = ptr_ty.childType(mod); |
| 5677 | const fn_info = mod.typeToFunc(self.dg.decl.ty).?; | 5667 | const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?; |
| 5678 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 5668 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 5679 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { | 5669 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { |
| 5680 | // Functions with an empty error set are emitted with an error code | 5670 | // Functions with an empty error set are emitted with an error code |
| ... | @@ -10067,10 +10057,7 @@ pub const FuncGen = struct { | ... | @@ -10067,10 +10057,7 @@ pub const FuncGen = struct { |
| 10067 | const elem_ptr = try self.wip.gep(.inbounds, llvm_result_ty, alloca_inst, &.{ | 10057 | const elem_ptr = try self.wip.gep(.inbounds, llvm_result_ty, alloca_inst, &.{ |
| 10068 | usize_zero, try o.builder.intValue(llvm_usize, array_info.len), | 10058 | usize_zero, try o.builder.intValue(llvm_usize, array_info.len), |
| 10069 | }, ""); | 10059 | }, ""); |
| 10070 | const llvm_elem = try self.resolveValue(.{ | 10060 | const llvm_elem = try self.resolveValue(sent_val); |
| 10071 | .ty = array_info.elem_type, | ||
| 10072 | .val = sent_val, | ||
| 10073 | }); | ||
| 10074 | try self.store(elem_ptr, elem_ptr_ty, llvm_elem.toValue(), .none); | 10061 | try self.store(elem_ptr, elem_ptr_ty, llvm_elem.toValue(), .none); |
| 10075 | } | 10062 | } |
| 10076 | 10063 |
src/codegen/spirv.zig+11-12| ... | @@ -255,7 +255,6 @@ pub const Object = struct { | ... | @@ -255,7 +255,6 @@ pub const Object = struct { |
| 255 | pub fn resolveDecl(self: *Object, mod: *Module, decl_index: InternPool.DeclIndex) !SpvModule.Decl.Index { | 255 | pub fn resolveDecl(self: *Object, mod: *Module, decl_index: InternPool.DeclIndex) !SpvModule.Decl.Index { |
| 256 | const decl = mod.declPtr(decl_index); | 256 | const decl = mod.declPtr(decl_index); |
| 257 | assert(decl.has_tv); // TODO: Do we need to handle a situation where this is false? | 257 | assert(decl.has_tv); // TODO: Do we need to handle a situation where this is false? |
| 258 | try mod.markDeclAlive(decl); | ||
| 259 | 258 | ||
| 260 | const entry = try self.decl_link.getOrPut(self.gpa, decl_index); | 259 | const entry = try self.decl_link.getOrPut(self.gpa, decl_index); |
| 261 | if (!entry.found_existing) { | 260 | if (!entry.found_existing) { |
| ... | @@ -861,7 +860,7 @@ const DeclGen = struct { | ... | @@ -861,7 +860,7 @@ const DeclGen = struct { |
| 861 | 860 | ||
| 862 | const val = arg_val; | 861 | const val = arg_val; |
| 863 | 862 | ||
| 864 | log.debug("constant: ty = {}, val = {}", .{ ty.fmt(mod), val.fmtValue(ty, mod) }); | 863 | log.debug("constant: ty = {}, val = {}", .{ ty.fmt(mod), val.fmtValue(mod) }); |
| 865 | if (val.isUndefDeep(mod)) { | 864 | if (val.isUndefDeep(mod)) { |
| 866 | return self.spv.constUndef(result_ty_ref); | 865 | return self.spv.constUndef(result_ty_ref); |
| 867 | } | 866 | } |
| ... | @@ -1221,7 +1220,7 @@ const DeclGen = struct { | ... | @@ -1221,7 +1220,7 @@ const DeclGen = struct { |
| 1221 | else => {}, | 1220 | else => {}, |
| 1222 | } | 1221 | } |
| 1223 | 1222 | ||
| 1224 | if (!decl.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) { | 1223 | if (!decl.typeOf(mod).isFnOrHasRuntimeBitsIgnoreComptime(mod)) { |
| 1225 | // Pointer to nothing - return undefined. | 1224 | // Pointer to nothing - return undefined. |
| 1226 | return self.spv.constUndef(ty_ref); | 1225 | return self.spv.constUndef(ty_ref); |
| 1227 | } | 1226 | } |
| ... | @@ -1237,7 +1236,7 @@ const DeclGen = struct { | ... | @@ -1237,7 +1236,7 @@ const DeclGen = struct { |
| 1237 | const final_storage_class = self.spvStorageClass(decl.@"addrspace"); | 1236 | const final_storage_class = self.spvStorageClass(decl.@"addrspace"); |
| 1238 | try self.addFunctionDep(spv_decl_index, final_storage_class); | 1237 | try self.addFunctionDep(spv_decl_index, final_storage_class); |
| 1239 | 1238 | ||
| 1240 | const decl_ptr_ty_ref = try self.ptrType(decl.ty, final_storage_class); | 1239 | const decl_ptr_ty_ref = try self.ptrType(decl.typeOf(mod), final_storage_class); |
| 1241 | 1240 | ||
| 1242 | const ptr_id = switch (final_storage_class) { | 1241 | const ptr_id = switch (final_storage_class) { |
| 1243 | .Generic => try self.castToGeneric(self.typeId(decl_ptr_ty_ref), decl_id), | 1242 | .Generic => try self.castToGeneric(self.typeId(decl_ptr_ty_ref), decl_id), |
| ... | @@ -2044,11 +2043,11 @@ const DeclGen = struct { | ... | @@ -2044,11 +2043,11 @@ const DeclGen = struct { |
| 2044 | 2043 | ||
| 2045 | switch (self.spv.declPtr(spv_decl_index).kind) { | 2044 | switch (self.spv.declPtr(spv_decl_index).kind) { |
| 2046 | .func => { | 2045 | .func => { |
| 2047 | assert(decl.ty.zigTypeTag(mod) == .Fn); | 2046 | assert(decl.typeOf(mod).zigTypeTag(mod) == .Fn); |
| 2048 | const fn_info = mod.typeToFunc(decl.ty).?; | 2047 | const fn_info = mod.typeToFunc(decl.typeOf(mod)).?; |
| 2049 | const return_ty_ref = try self.resolveFnReturnType(Type.fromInterned(fn_info.return_type)); | 2048 | const return_ty_ref = try self.resolveFnReturnType(Type.fromInterned(fn_info.return_type)); |
| 2050 | 2049 | ||
| 2051 | const prototype_ty_ref = try self.resolveType(decl.ty, .direct); | 2050 | const prototype_ty_ref = try self.resolveType(decl.typeOf(mod), .direct); |
| 2052 | try self.func.prologue.emit(self.spv.gpa, .OpFunction, .{ | 2051 | try self.func.prologue.emit(self.spv.gpa, .OpFunction, .{ |
| 2053 | .id_result_type = self.typeId(return_ty_ref), | 2052 | .id_result_type = self.typeId(return_ty_ref), |
| 2054 | .id_result = result_id, | 2053 | .id_result = result_id, |
| ... | @@ -2121,7 +2120,7 @@ const DeclGen = struct { | ... | @@ -2121,7 +2120,7 @@ const DeclGen = struct { |
| 2121 | const final_storage_class = self.spvStorageClass(decl.@"addrspace"); | 2120 | const final_storage_class = self.spvStorageClass(decl.@"addrspace"); |
| 2122 | assert(final_storage_class != .Generic); // These should be instance globals | 2121 | assert(final_storage_class != .Generic); // These should be instance globals |
| 2123 | 2122 | ||
| 2124 | const ptr_ty_ref = try self.ptrType(decl.ty, final_storage_class); | 2123 | const ptr_ty_ref = try self.ptrType(decl.typeOf(mod), final_storage_class); |
| 2125 | 2124 | ||
| 2126 | try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpVariable, .{ | 2125 | try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpVariable, .{ |
| 2127 | .id_result_type = self.typeId(ptr_ty_ref), | 2126 | .id_result_type = self.typeId(ptr_ty_ref), |
| ... | @@ -2144,7 +2143,7 @@ const DeclGen = struct { | ... | @@ -2144,7 +2143,7 @@ const DeclGen = struct { |
| 2144 | 2143 | ||
| 2145 | try self.spv.declareDeclDeps(spv_decl_index, &.{}); | 2144 | try self.spv.declareDeclDeps(spv_decl_index, &.{}); |
| 2146 | 2145 | ||
| 2147 | const ptr_ty_ref = try self.ptrType(decl.ty, .Function); | 2146 | const ptr_ty_ref = try self.ptrType(decl.typeOf(mod), .Function); |
| 2148 | 2147 | ||
| 2149 | if (maybe_init_val) |init_val| { | 2148 | if (maybe_init_val) |init_val| { |
| 2150 | // TODO: Combine with resolveAnonDecl? | 2149 | // TODO: Combine with resolveAnonDecl? |
| ... | @@ -2168,7 +2167,7 @@ const DeclGen = struct { | ... | @@ -2168,7 +2167,7 @@ const DeclGen = struct { |
| 2168 | }); | 2167 | }); |
| 2169 | self.current_block_label = root_block_id; | 2168 | self.current_block_label = root_block_id; |
| 2170 | 2169 | ||
| 2171 | const val_id = try self.constant(decl.ty, init_val, .indirect); | 2170 | const val_id = try self.constant(decl.typeOf(mod), init_val, .indirect); |
| 2172 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ | 2171 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ |
| 2173 | .pointer = result_id, | 2172 | .pointer = result_id, |
| 2174 | .object = val_id, | 2173 | .object = val_id, |
| ... | @@ -4785,7 +4784,7 @@ const DeclGen = struct { | ... | @@ -4785,7 +4784,7 @@ const DeclGen = struct { |
| 4785 | const mod = self.module; | 4784 | const mod = self.module; |
| 4786 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4785 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 4787 | const decl = mod.declPtr(self.decl_index); | 4786 | const decl = mod.declPtr(self.decl_index); |
| 4788 | const fn_info = mod.typeToFunc(decl.ty).?; | 4787 | const fn_info = mod.typeToFunc(decl.typeOf(mod)).?; |
| 4789 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { | 4788 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { |
| 4790 | // Functions with an empty error set are emitted with an error code | 4789 | // Functions with an empty error set are emitted with an error code |
| 4791 | // return type and return zero so they can be function pointers coerced | 4790 | // return type and return zero so they can be function pointers coerced |
| ... | @@ -4810,7 +4809,7 @@ const DeclGen = struct { | ... | @@ -4810,7 +4809,7 @@ const DeclGen = struct { |
| 4810 | 4809 | ||
| 4811 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4810 | if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 4812 | const decl = mod.declPtr(self.decl_index); | 4811 | const decl = mod.declPtr(self.decl_index); |
| 4813 | const fn_info = mod.typeToFunc(decl.ty).?; | 4812 | const fn_info = mod.typeToFunc(decl.typeOf(mod)).?; |
| 4814 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { | 4813 | if (Type.fromInterned(fn_info.return_type).isError(mod)) { |
| 4815 | // Functions with an empty error set are emitted with an error code | 4814 | // Functions with an empty error set are emitted with an error code |
| 4816 | // return type and return zero so they can be function pointers coerced | 4815 | // return type and return zero so they can be function pointers coerced |
src/link.zig+3-3| ... | @@ -17,7 +17,7 @@ const Liveness = @import("Liveness.zig"); | ... | @@ -17,7 +17,7 @@ const Liveness = @import("Liveness.zig"); |
| 17 | const Module = @import("Module.zig"); | 17 | const Module = @import("Module.zig"); |
| 18 | const InternPool = @import("InternPool.zig"); | 18 | const InternPool = @import("InternPool.zig"); |
| 19 | const Type = @import("type.zig").Type; | 19 | const Type = @import("type.zig").Type; |
| 20 | const TypedValue = @import("TypedValue.zig"); | 20 | const Value = @import("Value.zig"); |
| 21 | const LlvmObject = @import("codegen/llvm.zig").Object; | 21 | const LlvmObject = @import("codegen/llvm.zig").Object; |
| 22 | 22 | ||
| 23 | /// When adding a new field, remember to update `hashAddSystemLibs`. | 23 | /// When adding a new field, remember to update `hashAddSystemLibs`. |
| ... | @@ -376,14 +376,14 @@ pub const File = struct { | ... | @@ -376,14 +376,14 @@ pub const File = struct { |
| 376 | /// Called from within the CodeGen to lower a local variable instantion as an unnamed | 376 | /// Called from within the CodeGen to lower a local variable instantion as an unnamed |
| 377 | /// constant. Returns the symbol index of the lowered constant in the read-only section | 377 | /// constant. Returns the symbol index of the lowered constant in the read-only section |
| 378 | /// of the final binary. | 378 | /// of the final binary. |
| 379 | pub fn lowerUnnamedConst(base: *File, tv: TypedValue, decl_index: InternPool.DeclIndex) UpdateDeclError!u32 { | 379 | pub fn lowerUnnamedConst(base: *File, val: Value, decl_index: InternPool.DeclIndex) UpdateDeclError!u32 { |
| 380 | if (build_options.only_c) @compileError("unreachable"); | 380 | if (build_options.only_c) @compileError("unreachable"); |
| 381 | switch (base.tag) { | 381 | switch (base.tag) { |
| 382 | .spirv => unreachable, | 382 | .spirv => unreachable, |
| 383 | .c => unreachable, | 383 | .c => unreachable, |
| 384 | .nvptx => unreachable, | 384 | .nvptx => unreachable, |
| 385 | inline else => |t| { | 385 | inline else => |t| { |
| 386 | return @fieldParentPtr(t.Type(), "base", base).lowerUnnamedConst(tv, decl_index); | 386 | return @fieldParentPtr(t.Type(), "base", base).lowerUnnamedConst(val, decl_index); |
| 387 | }, | 387 | }, |
| 388 | } | 388 | } |
| 389 | } | 389 | } |
src/link/C.zig+2-6| ... | @@ -209,7 +209,7 @@ pub fn updateFunc( | ... | @@ -209,7 +209,7 @@ pub fn updateFunc( |
| 209 | .module = module, | 209 | .module = module, |
| 210 | .error_msg = null, | 210 | .error_msg = null, |
| 211 | .pass = .{ .decl = decl_index }, | 211 | .pass = .{ .decl = decl_index }, |
| 212 | .is_naked_fn = decl.ty.fnCallingConvention(module) == .Naked, | 212 | .is_naked_fn = decl.typeOf(module).fnCallingConvention(module) == .Naked, |
| 213 | .fwd_decl = fwd_decl.toManaged(gpa), | 213 | .fwd_decl = fwd_decl.toManaged(gpa), |
| 214 | .ctypes = ctypes.*, | 214 | .ctypes = ctypes.*, |
| 215 | .anon_decl_deps = self.anon_decls, | 215 | .anon_decl_deps = self.anon_decls, |
| ... | @@ -283,13 +283,9 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void { | ... | @@ -283,13 +283,9 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void { |
| 283 | code.* = object.code.moveToUnmanaged(); | 283 | code.* = object.code.moveToUnmanaged(); |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | const tv: @import("../TypedValue.zig") = .{ | ||
| 287 | .ty = Type.fromInterned(module.intern_pool.typeOf(anon_decl)), | ||
| 288 | .val = Value.fromInterned(anon_decl), | ||
| 289 | }; | ||
| 290 | const c_value: codegen.CValue = .{ .constant = anon_decl }; | 286 | const c_value: codegen.CValue = .{ .constant = anon_decl }; |
| 291 | const alignment: Alignment = self.aligned_anon_decls.get(anon_decl) orelse .none; | 287 | const alignment: Alignment = self.aligned_anon_decls.get(anon_decl) orelse .none; |
| 292 | codegen.genDeclValue(&object, tv, false, c_value, alignment, .none) catch |err| switch (err) { | 288 | codegen.genDeclValue(&object, Value.fromInterned(anon_decl), false, c_value, alignment, .none) catch |err| switch (err) { |
| 293 | error.AnalysisFail => { | 289 | error.AnalysisFail => { |
| 294 | @panic("TODO: C backend AnalysisFail on anonymous decl"); | 290 | @panic("TODO: C backend AnalysisFail on anonymous decl"); |
| 295 | //try module.failed_decls.put(gpa, decl_index, object.dg.error_msg.?); | 291 | //try module.failed_decls.put(gpa, decl_index, object.dg.error_msg.?); |
src/link/Coff.zig+9-13| ... | @@ -1167,7 +1167,7 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air: | ... | @@ -1167,7 +1167,7 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air: |
| 1167 | return self.updateExports(mod, .{ .decl_index = decl_index }, mod.getDeclExports(decl_index)); | 1167 | return self.updateExports(mod, .{ .decl_index = decl_index }, mod.getDeclExports(decl_index)); |
| 1168 | } | 1168 | } |
| 1169 | 1169 | ||
| 1170 | pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: InternPool.DeclIndex) !u32 { | 1170 | pub fn lowerUnnamedConst(self: *Coff, val: Value, decl_index: InternPool.DeclIndex) !u32 { |
| 1171 | const gpa = self.base.comp.gpa; | 1171 | const gpa = self.base.comp.gpa; |
| 1172 | const mod = self.base.comp.module.?; | 1172 | const mod = self.base.comp.module.?; |
| 1173 | const decl = mod.declPtr(decl_index); | 1173 | const decl = mod.declPtr(decl_index); |
| ... | @@ -1180,7 +1180,8 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: InternPool.Dec | ... | @@ -1180,7 +1180,8 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: InternPool.Dec |
| 1180 | const index = unnamed_consts.items.len; | 1180 | const index = unnamed_consts.items.len; |
| 1181 | const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index }); | 1181 | const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index }); |
| 1182 | defer gpa.free(sym_name); | 1182 | defer gpa.free(sym_name); |
| 1183 | const atom_index = switch (try self.lowerConst(sym_name, tv, tv.ty.abiAlignment(mod), self.rdata_section_index.?, decl.srcLoc(mod))) { | 1183 | const ty = val.typeOf(mod); |
| 1184 | const atom_index = switch (try self.lowerConst(sym_name, val, ty.abiAlignment(mod), self.rdata_section_index.?, decl.srcLoc(mod))) { | ||
| 1184 | .ok => |atom_index| atom_index, | 1185 | .ok => |atom_index| atom_index, |
| 1185 | .fail => |em| { | 1186 | .fail => |em| { |
| 1186 | decl.analysis = .codegen_failure; | 1187 | decl.analysis = .codegen_failure; |
| ... | @@ -1198,7 +1199,7 @@ const LowerConstResult = union(enum) { | ... | @@ -1198,7 +1199,7 @@ const LowerConstResult = union(enum) { |
| 1198 | fail: *Module.ErrorMsg, | 1199 | fail: *Module.ErrorMsg, |
| 1199 | }; | 1200 | }; |
| 1200 | 1201 | ||
| 1201 | fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, required_alignment: InternPool.Alignment, sect_id: u16, src_loc: Module.SrcLoc) !LowerConstResult { | 1202 | fn lowerConst(self: *Coff, name: []const u8, val: Value, required_alignment: InternPool.Alignment, sect_id: u16, src_loc: Module.SrcLoc) !LowerConstResult { |
| 1202 | const gpa = self.base.comp.gpa; | 1203 | const gpa = self.base.comp.gpa; |
| 1203 | 1204 | ||
| 1204 | var code_buffer = std.ArrayList(u8).init(gpa); | 1205 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | @@ -1209,7 +1210,7 @@ fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, required_alignment: | ... | @@ -1209,7 +1210,7 @@ fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, required_alignment: |
| 1209 | try self.setSymbolName(sym, name); | 1210 | try self.setSymbolName(sym, name); |
| 1210 | sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_id + 1)); | 1211 | sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_id + 1)); |
| 1211 | 1212 | ||
| 1212 | const res = try codegen.generateSymbol(&self.base, src_loc, tv, &code_buffer, .none, .{ | 1213 | const res = try codegen.generateSymbol(&self.base, src_loc, val, &code_buffer, .none, .{ |
| 1213 | .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?, | 1214 | .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?, |
| 1214 | }); | 1215 | }); |
| 1215 | const code = switch (res) { | 1216 | const code = switch (res) { |
| ... | @@ -1271,10 +1272,7 @@ pub fn updateDecl( | ... | @@ -1271,10 +1272,7 @@ pub fn updateDecl( |
| 1271 | defer code_buffer.deinit(); | 1272 | defer code_buffer.deinit(); |
| 1272 | 1273 | ||
| 1273 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; | 1274 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; |
| 1274 | const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{ | 1275 | const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), decl_val, &code_buffer, .none, .{ |
| 1275 | .ty = decl.ty, | ||
| 1276 | .val = decl_val, | ||
| 1277 | }, &code_buffer, .none, .{ | ||
| 1278 | .parent_atom_index = atom.getSymbolIndex().?, | 1276 | .parent_atom_index = atom.getSymbolIndex().?, |
| 1279 | }); | 1277 | }); |
| 1280 | const code = switch (res) { | 1278 | const code = switch (res) { |
| ... | @@ -1399,8 +1397,8 @@ pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: InternPool.DeclIndex) !At | ... | @@ -1399,8 +1397,8 @@ pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: InternPool.DeclIndex) !At |
| 1399 | 1397 | ||
| 1400 | fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 { | 1398 | fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 { |
| 1401 | const decl = self.base.comp.module.?.declPtr(decl_index); | 1399 | const decl = self.base.comp.module.?.declPtr(decl_index); |
| 1402 | const ty = decl.ty; | ||
| 1403 | const mod = self.base.comp.module.?; | 1400 | const mod = self.base.comp.module.?; |
| 1401 | const ty = decl.typeOf(mod); | ||
| 1404 | const zig_ty = ty.zigTypeTag(mod); | 1402 | const zig_ty = ty.zigTypeTag(mod); |
| 1405 | const val = decl.val; | 1403 | const val = decl.val; |
| 1406 | const index: u16 = blk: { | 1404 | const index: u16 = blk: { |
| ... | @@ -1535,7 +1533,7 @@ pub fn updateExports( | ... | @@ -1535,7 +1533,7 @@ pub fn updateExports( |
| 1535 | .x86 => std.builtin.CallingConvention.Stdcall, | 1533 | .x86 => std.builtin.CallingConvention.Stdcall, |
| 1536 | else => std.builtin.CallingConvention.C, | 1534 | else => std.builtin.CallingConvention.C, |
| 1537 | }; | 1535 | }; |
| 1538 | const decl_cc = exported_decl.ty.fnCallingConvention(mod); | 1536 | const decl_cc = exported_decl.typeOf(mod).fnCallingConvention(mod); |
| 1539 | if (decl_cc == .C and ip.stringEqlSlice(exp.opts.name, "main") and | 1537 | if (decl_cc == .C and ip.stringEqlSlice(exp.opts.name, "main") and |
| 1540 | comp.config.link_libc) | 1538 | comp.config.link_libc) |
| 1541 | { | 1539 | { |
| ... | @@ -1887,14 +1885,13 @@ pub fn lowerAnonDecl( | ... | @@ -1887,14 +1885,13 @@ pub fn lowerAnonDecl( |
| 1887 | } | 1885 | } |
| 1888 | 1886 | ||
| 1889 | const val = Value.fromInterned(decl_val); | 1887 | const val = Value.fromInterned(decl_val); |
| 1890 | const tv = TypedValue{ .ty = ty, .val = val }; | ||
| 1891 | var name_buf: [32]u8 = undefined; | 1888 | var name_buf: [32]u8 = undefined; |
| 1892 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ | 1889 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ |
| 1893 | @intFromEnum(decl_val), | 1890 | @intFromEnum(decl_val), |
| 1894 | }) catch unreachable; | 1891 | }) catch unreachable; |
| 1895 | const res = self.lowerConst( | 1892 | const res = self.lowerConst( |
| 1896 | name, | 1893 | name, |
| 1897 | tv, | 1894 | val, |
| 1898 | decl_alignment, | 1895 | decl_alignment, |
| 1899 | self.rdata_section_index.?, | 1896 | self.rdata_section_index.?, |
| 1900 | src_loc, | 1897 | src_loc, |
| ... | @@ -2754,7 +2751,6 @@ const TableSection = @import("table_section.zig").TableSection; | ... | @@ -2754,7 +2751,6 @@ const TableSection = @import("table_section.zig").TableSection; |
| 2754 | const StringTable = @import("StringTable.zig"); | 2751 | const StringTable = @import("StringTable.zig"); |
| 2755 | const Type = @import("../type.zig").Type; | 2752 | const Type = @import("../type.zig").Type; |
| 2756 | const Value = @import("../Value.zig"); | 2753 | const Value = @import("../Value.zig"); |
| 2757 | const TypedValue = @import("../TypedValue.zig"); | ||
| 2758 | 2754 | ||
| 2759 | pub const base_tag: link.File.Tag = .coff; | 2755 | pub const base_tag: link.File.Tag = .coff; |
| 2760 | 2756 |
src/link/Dwarf.zig+3-3| ... | @@ -1109,7 +1109,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde | ... | @@ -1109,7 +1109,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde |
| 1109 | 1109 | ||
| 1110 | assert(decl.has_tv); | 1110 | assert(decl.has_tv); |
| 1111 | 1111 | ||
| 1112 | switch (decl.ty.zigTypeTag(mod)) { | 1112 | switch (decl.typeOf(mod).zigTypeTag(mod)) { |
| 1113 | .Fn => { | 1113 | .Fn => { |
| 1114 | _ = try self.getOrCreateAtomForDecl(.src_fn, decl_index); | 1114 | _ = try self.getOrCreateAtomForDecl(.src_fn, decl_index); |
| 1115 | 1115 | ||
| ... | @@ -1162,7 +1162,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde | ... | @@ -1162,7 +1162,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde |
| 1162 | try dbg_info_buffer.ensureUnusedCapacity(1 + ptr_width_bytes + 4 + 4 + | 1162 | try dbg_info_buffer.ensureUnusedCapacity(1 + ptr_width_bytes + 4 + 4 + |
| 1163 | (decl_name_slice.len + 1) + (decl_linkage_name_slice.len + 1)); | 1163 | (decl_name_slice.len + 1) + (decl_linkage_name_slice.len + 1)); |
| 1164 | 1164 | ||
| 1165 | const fn_ret_type = decl.ty.fnReturnType(mod); | 1165 | const fn_ret_type = decl.typeOf(mod).fnReturnType(mod); |
| 1166 | const fn_ret_has_bits = fn_ret_type.hasRuntimeBits(mod); | 1166 | const fn_ret_has_bits = fn_ret_type.hasRuntimeBits(mod); |
| 1167 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum( | 1167 | dbg_info_buffer.appendAssumeCapacity(@intFromEnum( |
| 1168 | @as(AbbrevCode, if (fn_ret_has_bits) .subprogram else .subprogram_retvoid), | 1168 | @as(AbbrevCode, if (fn_ret_has_bits) .subprogram else .subprogram_retvoid), |
| ... | @@ -1215,7 +1215,7 @@ pub fn commitDeclState( | ... | @@ -1215,7 +1215,7 @@ pub fn commitDeclState( |
| 1215 | var dbg_info_buffer = &decl_state.dbg_info; | 1215 | var dbg_info_buffer = &decl_state.dbg_info; |
| 1216 | 1216 | ||
| 1217 | assert(decl.has_tv); | 1217 | assert(decl.has_tv); |
| 1218 | switch (decl.ty.zigTypeTag(zcu)) { | 1218 | switch (decl.typeOf(zcu).zigTypeTag(zcu)) { |
| 1219 | .Fn => { | 1219 | .Fn => { |
| 1220 | try decl_state.setInlineFunc(decl.val.toIntern()); | 1220 | try decl_state.setInlineFunc(decl.val.toIntern()); |
| 1221 | 1221 |
src/link/Elf.zig+3-3| ... | @@ -3039,8 +3039,8 @@ pub fn updateDecl( | ... | @@ -3039,8 +3039,8 @@ pub fn updateDecl( |
| 3039 | return self.zigObjectPtr().?.updateDecl(self, mod, decl_index); | 3039 | return self.zigObjectPtr().?.updateDecl(self, mod, decl_index); |
| 3040 | } | 3040 | } |
| 3041 | 3041 | ||
| 3042 | pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: InternPool.DeclIndex) !u32 { | 3042 | pub fn lowerUnnamedConst(self: *Elf, val: Value, decl_index: InternPool.DeclIndex) !u32 { |
| 3043 | return self.zigObjectPtr().?.lowerUnnamedConst(self, typed_value, decl_index); | 3043 | return self.zigObjectPtr().?.lowerUnnamedConst(self, val, decl_index); |
| 3044 | } | 3044 | } |
| 3045 | 3045 | ||
| 3046 | pub fn updateExports( | 3046 | pub fn updateExports( |
| ... | @@ -6260,7 +6260,7 @@ const SharedObject = @import("Elf/SharedObject.zig"); | ... | @@ -6260,7 +6260,7 @@ const SharedObject = @import("Elf/SharedObject.zig"); |
| 6260 | const Symbol = @import("Elf/Symbol.zig"); | 6260 | const Symbol = @import("Elf/Symbol.zig"); |
| 6261 | const StringTable = @import("StringTable.zig"); | 6261 | const StringTable = @import("StringTable.zig"); |
| 6262 | const Thunk = thunks.Thunk; | 6262 | const Thunk = thunks.Thunk; |
| 6263 | const TypedValue = @import("../TypedValue.zig"); | 6263 | const Value = @import("../Value.zig"); |
| 6264 | const VerneedSection = synthetic_sections.VerneedSection; | 6264 | const VerneedSection = synthetic_sections.VerneedSection; |
| 6265 | const ZigGotSection = synthetic_sections.ZigGotSection; | 6265 | const ZigGotSection = synthetic_sections.ZigGotSection; |
| 6266 | const ZigObject = @import("Elf/ZigObject.zig"); | 6266 | const ZigObject = @import("Elf/ZigObject.zig"); |
src/link/Elf/ZigObject.zig+10-17| ... | @@ -702,7 +702,6 @@ pub fn lowerAnonDecl( | ... | @@ -702,7 +702,6 @@ pub fn lowerAnonDecl( |
| 702 | } | 702 | } |
| 703 | 703 | ||
| 704 | const val = Value.fromInterned(decl_val); | 704 | const val = Value.fromInterned(decl_val); |
| 705 | const tv = TypedValue{ .ty = ty, .val = val }; | ||
| 706 | var name_buf: [32]u8 = undefined; | 705 | var name_buf: [32]u8 = undefined; |
| 707 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ | 706 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ |
| 708 | @intFromEnum(decl_val), | 707 | @intFromEnum(decl_val), |
| ... | @@ -710,7 +709,7 @@ pub fn lowerAnonDecl( | ... | @@ -710,7 +709,7 @@ pub fn lowerAnonDecl( |
| 710 | const res = self.lowerConst( | 709 | const res = self.lowerConst( |
| 711 | elf_file, | 710 | elf_file, |
| 712 | name, | 711 | name, |
| 713 | tv, | 712 | val, |
| 714 | decl_alignment, | 713 | decl_alignment, |
| 715 | elf_file.zig_data_rel_ro_section_index.?, | 714 | elf_file.zig_data_rel_ro_section_index.?, |
| 716 | src_loc, | 715 | src_loc, |
| ... | @@ -846,7 +845,7 @@ fn getDeclShdrIndex( | ... | @@ -846,7 +845,7 @@ fn getDeclShdrIndex( |
| 846 | _ = self; | 845 | _ = self; |
| 847 | const mod = elf_file.base.comp.module.?; | 846 | const mod = elf_file.base.comp.module.?; |
| 848 | const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded; | 847 | const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded; |
| 849 | const shdr_index = switch (decl.ty.zigTypeTag(mod)) { | 848 | const shdr_index = switch (decl.typeOf(mod).zigTypeTag(mod)) { |
| 850 | .Fn => elf_file.zig_text_section_index.?, | 849 | .Fn => elf_file.zig_text_section_index.?, |
| 851 | else => blk: { | 850 | else => blk: { |
| 852 | if (decl.getOwnedVariable(mod)) |variable| { | 851 | if (decl.getOwnedVariable(mod)) |variable| { |
| ... | @@ -1157,19 +1156,13 @@ pub fn updateDecl( | ... | @@ -1157,19 +1156,13 @@ pub fn updateDecl( |
| 1157 | // TODO implement .debug_info for global variables | 1156 | // TODO implement .debug_info for global variables |
| 1158 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; | 1157 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; |
| 1159 | const res = if (decl_state) |*ds| | 1158 | const res = if (decl_state) |*ds| |
| 1160 | try codegen.generateSymbol(&elf_file.base, decl.srcLoc(mod), .{ | 1159 | try codegen.generateSymbol(&elf_file.base, decl.srcLoc(mod), decl_val, &code_buffer, .{ |
| 1161 | .ty = decl.ty, | ||
| 1162 | .val = decl_val, | ||
| 1163 | }, &code_buffer, .{ | ||
| 1164 | .dwarf = ds, | 1160 | .dwarf = ds, |
| 1165 | }, .{ | 1161 | }, .{ |
| 1166 | .parent_atom_index = sym_index, | 1162 | .parent_atom_index = sym_index, |
| 1167 | }) | 1163 | }) |
| 1168 | else | 1164 | else |
| 1169 | try codegen.generateSymbol(&elf_file.base, decl.srcLoc(mod), .{ | 1165 | try codegen.generateSymbol(&elf_file.base, decl.srcLoc(mod), decl_val, &code_buffer, .none, .{ |
| 1170 | .ty = decl.ty, | ||
| 1171 | .val = decl_val, | ||
| 1172 | }, &code_buffer, .none, .{ | ||
| 1173 | .parent_atom_index = sym_index, | 1166 | .parent_atom_index = sym_index, |
| 1174 | }); | 1167 | }); |
| 1175 | 1168 | ||
| ... | @@ -1289,7 +1282,7 @@ fn updateLazySymbol( | ... | @@ -1289,7 +1282,7 @@ fn updateLazySymbol( |
| 1289 | pub fn lowerUnnamedConst( | 1282 | pub fn lowerUnnamedConst( |
| 1290 | self: *ZigObject, | 1283 | self: *ZigObject, |
| 1291 | elf_file: *Elf, | 1284 | elf_file: *Elf, |
| 1292 | typed_value: TypedValue, | 1285 | val: Value, |
| 1293 | decl_index: InternPool.DeclIndex, | 1286 | decl_index: InternPool.DeclIndex, |
| 1294 | ) !u32 { | 1287 | ) !u32 { |
| 1295 | const gpa = elf_file.base.comp.gpa; | 1288 | const gpa = elf_file.base.comp.gpa; |
| ... | @@ -1304,11 +1297,12 @@ pub fn lowerUnnamedConst( | ... | @@ -1304,11 +1297,12 @@ pub fn lowerUnnamedConst( |
| 1304 | const index = unnamed_consts.items.len; | 1297 | const index = unnamed_consts.items.len; |
| 1305 | const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index }); | 1298 | const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index }); |
| 1306 | defer gpa.free(name); | 1299 | defer gpa.free(name); |
| 1300 | const ty = val.typeOf(mod); | ||
| 1307 | const sym_index = switch (try self.lowerConst( | 1301 | const sym_index = switch (try self.lowerConst( |
| 1308 | elf_file, | 1302 | elf_file, |
| 1309 | name, | 1303 | name, |
| 1310 | typed_value, | 1304 | val, |
| 1311 | typed_value.ty.abiAlignment(mod), | 1305 | ty.abiAlignment(mod), |
| 1312 | elf_file.zig_data_rel_ro_section_index.?, | 1306 | elf_file.zig_data_rel_ro_section_index.?, |
| 1313 | decl.srcLoc(mod), | 1307 | decl.srcLoc(mod), |
| 1314 | )) { | 1308 | )) { |
| ... | @@ -1334,7 +1328,7 @@ fn lowerConst( | ... | @@ -1334,7 +1328,7 @@ fn lowerConst( |
| 1334 | self: *ZigObject, | 1328 | self: *ZigObject, |
| 1335 | elf_file: *Elf, | 1329 | elf_file: *Elf, |
| 1336 | name: []const u8, | 1330 | name: []const u8, |
| 1337 | tv: TypedValue, | 1331 | val: Value, |
| 1338 | required_alignment: InternPool.Alignment, | 1332 | required_alignment: InternPool.Alignment, |
| 1339 | output_section_index: u32, | 1333 | output_section_index: u32, |
| 1340 | src_loc: Module.SrcLoc, | 1334 | src_loc: Module.SrcLoc, |
| ... | @@ -1346,7 +1340,7 @@ fn lowerConst( | ... | @@ -1346,7 +1340,7 @@ fn lowerConst( |
| 1346 | 1340 | ||
| 1347 | const sym_index = try self.addAtom(elf_file); | 1341 | const sym_index = try self.addAtom(elf_file); |
| 1348 | 1342 | ||
| 1349 | const res = try codegen.generateSymbol(&elf_file.base, src_loc, tv, &code_buffer, .{ | 1343 | const res = try codegen.generateSymbol(&elf_file.base, src_loc, val, &code_buffer, .{ |
| 1350 | .none = {}, | 1344 | .none = {}, |
| 1351 | }, .{ | 1345 | }, .{ |
| 1352 | .parent_atom_index = sym_index, | 1346 | .parent_atom_index = sym_index, |
| ... | @@ -1657,5 +1651,4 @@ const Symbol = @import("Symbol.zig"); | ... | @@ -1657,5 +1651,4 @@ const Symbol = @import("Symbol.zig"); |
| 1657 | const StringTable = @import("../StringTable.zig"); | 1651 | const StringTable = @import("../StringTable.zig"); |
| 1658 | const Type = @import("../../type.zig").Type; | 1652 | const Type = @import("../../type.zig").Type; |
| 1659 | const Value = @import("../../Value.zig"); | 1653 | const Value = @import("../../Value.zig"); |
| 1660 | const TypedValue = @import("../../TypedValue.zig"); | ||
| 1661 | const ZigObject = @This(); | 1654 | const ZigObject = @This(); |
src/link/MachO.zig+3-3| ... | @@ -3127,8 +3127,8 @@ pub fn updateFunc(self: *MachO, mod: *Module, func_index: InternPool.Index, air: | ... | @@ -3127,8 +3127,8 @@ pub fn updateFunc(self: *MachO, mod: *Module, func_index: InternPool.Index, air: |
| 3127 | return self.getZigObject().?.updateFunc(self, mod, func_index, air, liveness); | 3127 | return self.getZigObject().?.updateFunc(self, mod, func_index, air, liveness); |
| 3128 | } | 3128 | } |
| 3129 | 3129 | ||
| 3130 | pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: InternPool.DeclIndex) !u32 { | 3130 | pub fn lowerUnnamedConst(self: *MachO, val: Value, decl_index: InternPool.DeclIndex) !u32 { |
| 3131 | return self.getZigObject().?.lowerUnnamedConst(self, typed_value, decl_index); | 3131 | return self.getZigObject().?.lowerUnnamedConst(self, val, decl_index); |
| 3132 | } | 3132 | } |
| 3133 | 3133 | ||
| 3134 | pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex) !void { | 3134 | pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex) !void { |
| ... | @@ -4689,7 +4689,7 @@ const StubsHelperSection = synthetic.StubsHelperSection; | ... | @@ -4689,7 +4689,7 @@ const StubsHelperSection = synthetic.StubsHelperSection; |
| 4689 | const Symbol = @import("MachO/Symbol.zig"); | 4689 | const Symbol = @import("MachO/Symbol.zig"); |
| 4690 | const Thunk = thunks.Thunk; | 4690 | const Thunk = thunks.Thunk; |
| 4691 | const TlvPtrSection = synthetic.TlvPtrSection; | 4691 | const TlvPtrSection = synthetic.TlvPtrSection; |
| 4692 | const TypedValue = @import("../TypedValue.zig"); | 4692 | const Value = @import("../Value.zig"); |
| 4693 | const UnwindInfo = @import("MachO/UnwindInfo.zig"); | 4693 | const UnwindInfo = @import("MachO/UnwindInfo.zig"); |
| 4694 | const WeakBindSection = synthetic.WeakBindSection; | 4694 | const WeakBindSection = synthetic.WeakBindSection; |
| 4695 | const ZigGotSection = synthetic.ZigGotSection; | 4695 | const ZigGotSection = synthetic.ZigGotSection; |
src/link/MachO/ZigObject.zig+8-15| ... | @@ -567,8 +567,6 @@ pub fn lowerAnonDecl( | ... | @@ -567,8 +567,6 @@ pub fn lowerAnonDecl( |
| 567 | return .ok; | 567 | return .ok; |
| 568 | } | 568 | } |
| 569 | 569 | ||
| 570 | const val = Value.fromInterned(decl_val); | ||
| 571 | const tv = TypedValue{ .ty = ty, .val = val }; | ||
| 572 | var name_buf: [32]u8 = undefined; | 570 | var name_buf: [32]u8 = undefined; |
| 573 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ | 571 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ |
| 574 | @intFromEnum(decl_val), | 572 | @intFromEnum(decl_val), |
| ... | @@ -576,7 +574,7 @@ pub fn lowerAnonDecl( | ... | @@ -576,7 +574,7 @@ pub fn lowerAnonDecl( |
| 576 | const res = self.lowerConst( | 574 | const res = self.lowerConst( |
| 577 | macho_file, | 575 | macho_file, |
| 578 | name, | 576 | name, |
| 579 | tv, | 577 | Value.fromInterned(decl_val), |
| 580 | decl_alignment, | 578 | decl_alignment, |
| 581 | macho_file.zig_const_sect_index.?, | 579 | macho_file.zig_const_sect_index.?, |
| 582 | src_loc, | 580 | src_loc, |
| ... | @@ -738,11 +736,7 @@ pub fn updateDecl( | ... | @@ -738,11 +736,7 @@ pub fn updateDecl( |
| 738 | 736 | ||
| 739 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; | 737 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; |
| 740 | const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none; | 738 | const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none; |
| 741 | const res = | 739 | const res = try codegen.generateSymbol(&macho_file.base, decl.srcLoc(mod), decl_val, &code_buffer, dio, .{ |
| 742 | try codegen.generateSymbol(&macho_file.base, decl.srcLoc(mod), .{ | ||
| 743 | .ty = decl.ty, | ||
| 744 | .val = decl_val, | ||
| 745 | }, &code_buffer, dio, .{ | ||
| 746 | .parent_atom_index = sym_index, | 740 | .parent_atom_index = sym_index, |
| 747 | }); | 741 | }); |
| 748 | 742 | ||
| ... | @@ -1021,7 +1015,7 @@ fn getDeclOutputSection( | ... | @@ -1021,7 +1015,7 @@ fn getDeclOutputSection( |
| 1021 | _ = self; | 1015 | _ = self; |
| 1022 | const mod = macho_file.base.comp.module.?; | 1016 | const mod = macho_file.base.comp.module.?; |
| 1023 | const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded; | 1017 | const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded; |
| 1024 | const sect_id: u8 = switch (decl.ty.zigTypeTag(mod)) { | 1018 | const sect_id: u8 = switch (decl.typeOf(mod).zigTypeTag(mod)) { |
| 1025 | .Fn => macho_file.zig_text_sect_index.?, | 1019 | .Fn => macho_file.zig_text_sect_index.?, |
| 1026 | else => blk: { | 1020 | else => blk: { |
| 1027 | if (decl.getOwnedVariable(mod)) |variable| { | 1021 | if (decl.getOwnedVariable(mod)) |variable| { |
| ... | @@ -1068,7 +1062,7 @@ fn getDeclOutputSection( | ... | @@ -1068,7 +1062,7 @@ fn getDeclOutputSection( |
| 1068 | pub fn lowerUnnamedConst( | 1062 | pub fn lowerUnnamedConst( |
| 1069 | self: *ZigObject, | 1063 | self: *ZigObject, |
| 1070 | macho_file: *MachO, | 1064 | macho_file: *MachO, |
| 1071 | typed_value: TypedValue, | 1065 | val: Value, |
| 1072 | decl_index: InternPool.DeclIndex, | 1066 | decl_index: InternPool.DeclIndex, |
| 1073 | ) !u32 { | 1067 | ) !u32 { |
| 1074 | const gpa = macho_file.base.comp.gpa; | 1068 | const gpa = macho_file.base.comp.gpa; |
| ... | @@ -1086,8 +1080,8 @@ pub fn lowerUnnamedConst( | ... | @@ -1086,8 +1080,8 @@ pub fn lowerUnnamedConst( |
| 1086 | const sym_index = switch (try self.lowerConst( | 1080 | const sym_index = switch (try self.lowerConst( |
| 1087 | macho_file, | 1081 | macho_file, |
| 1088 | name, | 1082 | name, |
| 1089 | typed_value, | 1083 | val, |
| 1090 | typed_value.ty.abiAlignment(mod), | 1084 | val.typeOf(mod).abiAlignment(mod), |
| 1091 | macho_file.zig_const_sect_index.?, | 1085 | macho_file.zig_const_sect_index.?, |
| 1092 | decl.srcLoc(mod), | 1086 | decl.srcLoc(mod), |
| 1093 | )) { | 1087 | )) { |
| ... | @@ -1113,7 +1107,7 @@ fn lowerConst( | ... | @@ -1113,7 +1107,7 @@ fn lowerConst( |
| 1113 | self: *ZigObject, | 1107 | self: *ZigObject, |
| 1114 | macho_file: *MachO, | 1108 | macho_file: *MachO, |
| 1115 | name: []const u8, | 1109 | name: []const u8, |
| 1116 | tv: TypedValue, | 1110 | val: Value, |
| 1117 | required_alignment: Atom.Alignment, | 1111 | required_alignment: Atom.Alignment, |
| 1118 | output_section_index: u8, | 1112 | output_section_index: u8, |
| 1119 | src_loc: Module.SrcLoc, | 1113 | src_loc: Module.SrcLoc, |
| ... | @@ -1125,7 +1119,7 @@ fn lowerConst( | ... | @@ -1125,7 +1119,7 @@ fn lowerConst( |
| 1125 | 1119 | ||
| 1126 | const sym_index = try self.addAtom(macho_file); | 1120 | const sym_index = try self.addAtom(macho_file); |
| 1127 | 1121 | ||
| 1128 | const res = try codegen.generateSymbol(&macho_file.base, src_loc, tv, &code_buffer, .{ | 1122 | const res = try codegen.generateSymbol(&macho_file.base, src_loc, val, &code_buffer, .{ |
| 1129 | .none = {}, | 1123 | .none = {}, |
| 1130 | }, .{ | 1124 | }, .{ |
| 1131 | .parent_atom_index = sym_index, | 1125 | .parent_atom_index = sym_index, |
| ... | @@ -1580,5 +1574,4 @@ const Symbol = @import("Symbol.zig"); | ... | @@ -1580,5 +1574,4 @@ const Symbol = @import("Symbol.zig"); |
| 1580 | const StringTable = @import("../StringTable.zig"); | 1574 | const StringTable = @import("../StringTable.zig"); |
| 1581 | const Type = @import("../../type.zig").Type; | 1575 | const Type = @import("../../type.zig").Type; |
| 1582 | const Value = @import("../../Value.zig"); | 1576 | const Value = @import("../../Value.zig"); |
| 1583 | const TypedValue = @import("../../TypedValue.zig"); | ||
| 1584 | const ZigObject = @This(); | 1577 | const ZigObject = @This(); |
src/link/Plan9.zig+6-13| ... | @@ -15,7 +15,6 @@ const Air = @import("../Air.zig"); | ... | @@ -15,7 +15,6 @@ const Air = @import("../Air.zig"); |
| 15 | const Liveness = @import("../Liveness.zig"); | 15 | const Liveness = @import("../Liveness.zig"); |
| 16 | const Type = @import("../type.zig").Type; | 16 | const Type = @import("../type.zig").Type; |
| 17 | const Value = @import("../Value.zig"); | 17 | const Value = @import("../Value.zig"); |
| 18 | const TypedValue = @import("../TypedValue.zig"); | ||
| 19 | 18 | ||
| 20 | const std = @import("std"); | 19 | const std = @import("std"); |
| 21 | const builtin = @import("builtin"); | 20 | const builtin = @import("builtin"); |
| ... | @@ -177,7 +176,7 @@ pub const Atom = struct { | ... | @@ -177,7 +176,7 @@ pub const Atom = struct { |
| 177 | return if (self.code_ptr) |p| p[0..self.other.code_len] else blk: { | 176 | return if (self.code_ptr) |p| p[0..self.other.code_len] else blk: { |
| 178 | const decl_index = self.other.decl_index; | 177 | const decl_index = self.other.decl_index; |
| 179 | const decl = mod.declPtr(decl_index); | 178 | const decl = mod.declPtr(decl_index); |
| 180 | if (decl.ty.zigTypeTag(mod) == .Fn) { | 179 | if (decl.typeOf(mod).zigTypeTag(mod) == .Fn) { |
| 181 | const table = plan9.fn_decl_table.get(decl.getFileScope(mod)).?.functions; | 180 | const table = plan9.fn_decl_table.get(decl.getFileScope(mod)).?.functions; |
| 182 | const output = table.get(decl_index).?; | 181 | const output = table.get(decl_index).?; |
| 183 | break :blk output.code; | 182 | break :blk output.code; |
| ... | @@ -463,7 +462,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: | ... | @@ -463,7 +462,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: |
| 463 | return self.updateFinish(decl_index); | 462 | return self.updateFinish(decl_index); |
| 464 | } | 463 | } |
| 465 | 464 | ||
| 466 | pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: InternPool.DeclIndex) !u32 { | 465 | pub fn lowerUnnamedConst(self: *Plan9, val: Value, decl_index: InternPool.DeclIndex) !u32 { |
| 467 | const gpa = self.base.comp.gpa; | 466 | const gpa = self.base.comp.gpa; |
| 468 | _ = try self.seeDecl(decl_index); | 467 | _ = try self.seeDecl(decl_index); |
| 469 | var code_buffer = std.ArrayList(u8).init(gpa); | 468 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | @@ -500,7 +499,7 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: InternPool.De | ... | @@ -500,7 +499,7 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: InternPool.De |
| 500 | }; | 499 | }; |
| 501 | self.syms.items[info.sym_index.?] = sym; | 500 | self.syms.items[info.sym_index.?] = sym; |
| 502 | 501 | ||
| 503 | const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), tv, &code_buffer, .{ | 502 | const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), val, &code_buffer, .{ |
| 504 | .none = {}, | 503 | .none = {}, |
| 505 | }, .{ | 504 | }, .{ |
| 506 | .parent_atom_index = new_atom_idx, | 505 | .parent_atom_index = new_atom_idx, |
| ... | @@ -539,10 +538,7 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex) | ... | @@ -539,10 +538,7 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex) |
| 539 | defer code_buffer.deinit(); | 538 | defer code_buffer.deinit(); |
| 540 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; | 539 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; |
| 541 | // TODO we need the symbol index for symbol in the table of locals for the containing atom | 540 | // TODO we need the symbol index for symbol in the table of locals for the containing atom |
| 542 | const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{ | 541 | const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), decl_val, &code_buffer, .{ .none = {} }, .{ |
| 543 | .ty = decl.ty, | ||
| 544 | .val = decl_val, | ||
| 545 | }, &code_buffer, .{ .none = {} }, .{ | ||
| 546 | .parent_atom_index = @as(Atom.Index, @intCast(atom_idx)), | 542 | .parent_atom_index = @as(Atom.Index, @intCast(atom_idx)), |
| 547 | }); | 543 | }); |
| 548 | const code = switch (res) { | 544 | const code = switch (res) { |
| ... | @@ -566,7 +562,7 @@ fn updateFinish(self: *Plan9, decl_index: InternPool.DeclIndex) !void { | ... | @@ -566,7 +562,7 @@ fn updateFinish(self: *Plan9, decl_index: InternPool.DeclIndex) !void { |
| 566 | const gpa = self.base.comp.gpa; | 562 | const gpa = self.base.comp.gpa; |
| 567 | const mod = self.base.comp.module.?; | 563 | const mod = self.base.comp.module.?; |
| 568 | const decl = mod.declPtr(decl_index); | 564 | const decl = mod.declPtr(decl_index); |
| 569 | const is_fn = (decl.ty.zigTypeTag(mod) == .Fn); | 565 | const is_fn = (decl.typeOf(mod).zigTypeTag(mod) == .Fn); |
| 570 | const sym_t: aout.Sym.Type = if (is_fn) .t else .d; | 566 | const sym_t: aout.Sym.Type = if (is_fn) .t else .d; |
| 571 | 567 | ||
| 572 | const atom = self.getAtomPtr(self.decls.get(decl_index).?.index); | 568 | const atom = self.getAtomPtr(self.decls.get(decl_index).?.index); |
| ... | @@ -1545,11 +1541,8 @@ pub fn lowerAnonDecl( | ... | @@ -1545,11 +1541,8 @@ pub fn lowerAnonDecl( |
| 1545 | // ... | 1541 | // ... |
| 1546 | const gpa = self.base.comp.gpa; | 1542 | const gpa = self.base.comp.gpa; |
| 1547 | const gop = try self.anon_decls.getOrPut(gpa, decl_val); | 1543 | const gop = try self.anon_decls.getOrPut(gpa, decl_val); |
| 1548 | const mod = self.base.comp.module.?; | ||
| 1549 | if (!gop.found_existing) { | 1544 | if (!gop.found_existing) { |
| 1550 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); | ||
| 1551 | const val = Value.fromInterned(decl_val); | 1545 | const val = Value.fromInterned(decl_val); |
| 1552 | const tv = TypedValue{ .ty = ty, .val = val }; | ||
| 1553 | const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)}); | 1546 | const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)}); |
| 1554 | 1547 | ||
| 1555 | const index = try self.createAtom(); | 1548 | const index = try self.createAtom(); |
| ... | @@ -1557,7 +1550,7 @@ pub fn lowerAnonDecl( | ... | @@ -1557,7 +1550,7 @@ pub fn lowerAnonDecl( |
| 1557 | gop.value_ptr.* = index; | 1550 | gop.value_ptr.* = index; |
| 1558 | // we need to free name latex | 1551 | // we need to free name latex |
| 1559 | var code_buffer = std.ArrayList(u8).init(gpa); | 1552 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 1560 | const res = try codegen.generateSymbol(&self.base, src_loc, tv, &code_buffer, .{ .none = {} }, .{ .parent_atom_index = index }); | 1553 | const res = try codegen.generateSymbol(&self.base, src_loc, val, &code_buffer, .{ .none = {} }, .{ .parent_atom_index = index }); |
| 1561 | const code = switch (res) { | 1554 | const code = switch (res) { |
| 1562 | .ok => code_buffer.items, | 1555 | .ok => code_buffer.items, |
| 1563 | .fail => |em| return .{ .fail = em }, | 1556 | .fail => |em| return .{ .fail = em }, |
src/link/SpirV.zig+1-1| ... | @@ -163,7 +163,7 @@ pub fn updateExports( | ... | @@ -163,7 +163,7 @@ pub fn updateExports( |
| 163 | if (decl.val.isFuncBody(mod)) { | 163 | if (decl.val.isFuncBody(mod)) { |
| 164 | const target = mod.getTarget(); | 164 | const target = mod.getTarget(); |
| 165 | const spv_decl_index = try self.object.resolveDecl(mod, decl_index); | 165 | const spv_decl_index = try self.object.resolveDecl(mod, decl_index); |
| 166 | const execution_model = switch (decl.ty.fnCallingConvention(mod)) { | 166 | const execution_model = switch (decl.typeOf(mod).fnCallingConvention(mod)) { |
| 167 | .Vertex => spec.ExecutionModel.Vertex, | 167 | .Vertex => spec.ExecutionModel.Vertex, |
| 168 | .Fragment => spec.ExecutionModel.Fragment, | 168 | .Fragment => spec.ExecutionModel.Fragment, |
| 169 | .Kernel => spec.ExecutionModel.Kernel, | 169 | .Kernel => spec.ExecutionModel.Kernel, |
src/link/Wasm.zig+3-3| ... | @@ -32,7 +32,7 @@ const Module = @import("../Module.zig"); | ... | @@ -32,7 +32,7 @@ const Module = @import("../Module.zig"); |
| 32 | const Object = @import("Wasm/Object.zig"); | 32 | const Object = @import("Wasm/Object.zig"); |
| 33 | const Symbol = @import("Wasm/Symbol.zig"); | 33 | const Symbol = @import("Wasm/Symbol.zig"); |
| 34 | const Type = @import("../type.zig").Type; | 34 | const Type = @import("../type.zig").Type; |
| 35 | const TypedValue = @import("../TypedValue.zig"); | 35 | const Value = @import("../Value.zig"); |
| 36 | const ZigObject = @import("Wasm/ZigObject.zig"); | 36 | const ZigObject = @import("Wasm/ZigObject.zig"); |
| 37 | 37 | ||
| 38 | pub const Atom = @import("Wasm/Atom.zig"); | 38 | pub const Atom = @import("Wasm/Atom.zig"); |
| ... | @@ -1504,8 +1504,8 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type { | ... | @@ -1504,8 +1504,8 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type { |
| 1504 | /// Lowers a constant typed value to a local symbol and atom. | 1504 | /// Lowers a constant typed value to a local symbol and atom. |
| 1505 | /// Returns the symbol index of the local | 1505 | /// Returns the symbol index of the local |
| 1506 | /// The given `decl` is the parent decl whom owns the constant. | 1506 | /// The given `decl` is the parent decl whom owns the constant. |
| 1507 | pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: InternPool.DeclIndex) !u32 { | 1507 | pub fn lowerUnnamedConst(wasm: *Wasm, val: Value, decl_index: InternPool.DeclIndex) !u32 { |
| 1508 | return wasm.zigObjectPtr().?.lowerUnnamedConst(wasm, tv, decl_index); | 1508 | return wasm.zigObjectPtr().?.lowerUnnamedConst(wasm, val, decl_index); |
| 1509 | } | 1509 | } |
| 1510 | 1510 | ||
| 1511 | /// Returns the symbol index from a symbol of which its flag is set global, | 1511 | /// Returns the symbol index from a symbol of which its flag is set global, |
src/link/Wasm/ZigObject.zig+14-16| ... | @@ -270,7 +270,7 @@ pub fn updateDecl( | ... | @@ -270,7 +270,7 @@ pub fn updateDecl( |
| 270 | const res = try codegen.generateSymbol( | 270 | const res = try codegen.generateSymbol( |
| 271 | &wasm_file.base, | 271 | &wasm_file.base, |
| 272 | decl.srcLoc(mod), | 272 | decl.srcLoc(mod), |
| 273 | .{ .ty = decl.ty, .val = val }, | 273 | val, |
| 274 | &code_writer, | 274 | &code_writer, |
| 275 | .none, | 275 | .none, |
| 276 | .{ .parent_atom_index = @intFromEnum(atom.sym_index) }, | 276 | .{ .parent_atom_index = @intFromEnum(atom.sym_index) }, |
| ... | @@ -346,7 +346,7 @@ fn finishUpdateDecl( | ... | @@ -346,7 +346,7 @@ fn finishUpdateDecl( |
| 346 | try atom.code.appendSlice(gpa, code); | 346 | try atom.code.appendSlice(gpa, code); |
| 347 | atom.size = @intCast(code.len); | 347 | atom.size = @intCast(code.len); |
| 348 | 348 | ||
| 349 | switch (decl.ty.zigTypeTag(mod)) { | 349 | switch (decl.typeOf(mod).zigTypeTag(mod)) { |
| 350 | .Fn => { | 350 | .Fn => { |
| 351 | sym.index = try zig_object.appendFunction(gpa, .{ .type_index = zig_object.atom_types.get(atom_index).? }); | 351 | sym.index = try zig_object.appendFunction(gpa, .{ .type_index = zig_object.atom_types.get(atom_index).? }); |
| 352 | sym.tag = .function; | 352 | sym.tag = .function; |
| ... | @@ -444,15 +444,12 @@ pub fn lowerAnonDecl( | ... | @@ -444,15 +444,12 @@ pub fn lowerAnonDecl( |
| 444 | const gpa = wasm_file.base.comp.gpa; | 444 | const gpa = wasm_file.base.comp.gpa; |
| 445 | const gop = try zig_object.anon_decls.getOrPut(gpa, decl_val); | 445 | const gop = try zig_object.anon_decls.getOrPut(gpa, decl_val); |
| 446 | if (!gop.found_existing) { | 446 | if (!gop.found_existing) { |
| 447 | const mod = wasm_file.base.comp.module.?; | ||
| 448 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); | ||
| 449 | const tv: TypedValue = .{ .ty = ty, .val = Value.fromInterned(decl_val) }; | ||
| 450 | var name_buf: [32]u8 = undefined; | 447 | var name_buf: [32]u8 = undefined; |
| 451 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ | 448 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ |
| 452 | @intFromEnum(decl_val), | 449 | @intFromEnum(decl_val), |
| 453 | }) catch unreachable; | 450 | }) catch unreachable; |
| 454 | 451 | ||
| 455 | switch (try zig_object.lowerConst(wasm_file, name, tv, src_loc)) { | 452 | switch (try zig_object.lowerConst(wasm_file, name, Value.fromInterned(decl_val), src_loc)) { |
| 456 | .ok => |atom_index| zig_object.anon_decls.values()[gop.index] = atom_index, | 453 | .ok => |atom_index| zig_object.anon_decls.values()[gop.index] = atom_index, |
| 457 | .fail => |em| return .{ .fail = em }, | 454 | .fail => |em| return .{ .fail = em }, |
| 458 | } | 455 | } |
| ... | @@ -472,10 +469,10 @@ pub fn lowerAnonDecl( | ... | @@ -472,10 +469,10 @@ pub fn lowerAnonDecl( |
| 472 | /// Lowers a constant typed value to a local symbol and atom. | 469 | /// Lowers a constant typed value to a local symbol and atom. |
| 473 | /// Returns the symbol index of the local | 470 | /// Returns the symbol index of the local |
| 474 | /// The given `decl` is the parent decl whom owns the constant. | 471 | /// The given `decl` is the parent decl whom owns the constant. |
| 475 | pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, tv: TypedValue, decl_index: InternPool.DeclIndex) !u32 { | 472 | pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, decl_index: InternPool.DeclIndex) !u32 { |
| 476 | const gpa = wasm_file.base.comp.gpa; | 473 | const gpa = wasm_file.base.comp.gpa; |
| 477 | const mod = wasm_file.base.comp.module.?; | 474 | const mod = wasm_file.base.comp.module.?; |
| 478 | std.debug.assert(tv.ty.zigTypeTag(mod) != .Fn); // cannot create local symbols for functions | 475 | std.debug.assert(val.typeOf(mod).zigTypeTag(mod) != .Fn); // cannot create local symbols for functions |
| 479 | const decl = mod.declPtr(decl_index); | 476 | const decl = mod.declPtr(decl_index); |
| 480 | 477 | ||
| 481 | const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index); | 478 | const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, decl_index); |
| ... | @@ -487,7 +484,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, tv: TypedValu | ... | @@ -487,7 +484,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, tv: TypedValu |
| 487 | }); | 484 | }); |
| 488 | defer gpa.free(name); | 485 | defer gpa.free(name); |
| 489 | 486 | ||
| 490 | switch (try zig_object.lowerConst(wasm_file, name, tv, decl.srcLoc(mod))) { | 487 | switch (try zig_object.lowerConst(wasm_file, name, val, decl.srcLoc(mod))) { |
| 491 | .ok => |atom_index| { | 488 | .ok => |atom_index| { |
| 492 | try wasm_file.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index); | 489 | try wasm_file.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index); |
| 493 | return @intFromEnum(wasm_file.getAtom(atom_index).sym_index); | 490 | return @intFromEnum(wasm_file.getAtom(atom_index).sym_index); |
| ... | @@ -505,10 +502,12 @@ const LowerConstResult = union(enum) { | ... | @@ -505,10 +502,12 @@ const LowerConstResult = union(enum) { |
| 505 | fail: *Module.ErrorMsg, | 502 | fail: *Module.ErrorMsg, |
| 506 | }; | 503 | }; |
| 507 | 504 | ||
| 508 | fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: TypedValue, src_loc: Module.SrcLoc) !LowerConstResult { | 505 | fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, val: Value, src_loc: Module.SrcLoc) !LowerConstResult { |
| 509 | const gpa = wasm_file.base.comp.gpa; | 506 | const gpa = wasm_file.base.comp.gpa; |
| 510 | const mod = wasm_file.base.comp.module.?; | 507 | const mod = wasm_file.base.comp.module.?; |
| 511 | 508 | ||
| 509 | const ty = val.typeOf(mod); | ||
| 510 | |||
| 512 | // Create and initialize a new local symbol and atom | 511 | // Create and initialize a new local symbol and atom |
| 513 | const sym_index = try zig_object.allocateSymbol(gpa); | 512 | const sym_index = try zig_object.allocateSymbol(gpa); |
| 514 | const atom_index = try wasm_file.createAtom(sym_index, zig_object.index); | 513 | const atom_index = try wasm_file.createAtom(sym_index, zig_object.index); |
| ... | @@ -517,7 +516,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty | ... | @@ -517,7 +516,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty |
| 517 | 516 | ||
| 518 | const code = code: { | 517 | const code = code: { |
| 519 | const atom = wasm_file.getAtomPtr(atom_index); | 518 | const atom = wasm_file.getAtomPtr(atom_index); |
| 520 | atom.alignment = tv.ty.abiAlignment(mod); | 519 | atom.alignment = ty.abiAlignment(mod); |
| 521 | const segment_name = try std.mem.concat(gpa, u8, &.{ ".rodata.", name }); | 520 | const segment_name = try std.mem.concat(gpa, u8, &.{ ".rodata.", name }); |
| 522 | errdefer gpa.free(segment_name); | 521 | errdefer gpa.free(segment_name); |
| 523 | zig_object.symbol(sym_index).* = .{ | 522 | zig_object.symbol(sym_index).* = .{ |
| ... | @@ -527,7 +526,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty | ... | @@ -527,7 +526,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty |
| 527 | .index = try zig_object.createDataSegment( | 526 | .index = try zig_object.createDataSegment( |
| 528 | gpa, | 527 | gpa, |
| 529 | segment_name, | 528 | segment_name, |
| 530 | tv.ty.abiAlignment(mod), | 529 | ty.abiAlignment(mod), |
| 531 | ), | 530 | ), |
| 532 | .virtual_address = undefined, | 531 | .virtual_address = undefined, |
| 533 | }; | 532 | }; |
| ... | @@ -535,7 +534,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty | ... | @@ -535,7 +534,7 @@ fn lowerConst(zig_object: *ZigObject, wasm_file: *Wasm, name: []const u8, tv: Ty |
| 535 | const result = try codegen.generateSymbol( | 534 | const result = try codegen.generateSymbol( |
| 536 | &wasm_file.base, | 535 | &wasm_file.base, |
| 537 | src_loc, | 536 | src_loc, |
| 538 | tv, | 537 | val, |
| 539 | &value_bytes, | 538 | &value_bytes, |
| 540 | .none, | 539 | .none, |
| 541 | .{ | 540 | .{ |
| ... | @@ -764,7 +763,7 @@ pub fn getDeclVAddr( | ... | @@ -764,7 +763,7 @@ pub fn getDeclVAddr( |
| 764 | const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?; | 763 | const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?; |
| 765 | const atom = wasm_file.getAtomPtr(atom_index); | 764 | const atom = wasm_file.getAtomPtr(atom_index); |
| 766 | const is_wasm32 = target.cpu.arch == .wasm32; | 765 | const is_wasm32 = target.cpu.arch == .wasm32; |
| 767 | if (decl.ty.zigTypeTag(mod) == .Fn) { | 766 | if (decl.typeOf(mod).zigTypeTag(mod) == .Fn) { |
| 768 | std.debug.assert(reloc_info.addend == 0); // addend not allowed for function relocations | 767 | std.debug.assert(reloc_info.addend == 0); // addend not allowed for function relocations |
| 769 | try atom.relocs.append(gpa, .{ | 768 | try atom.relocs.append(gpa, .{ |
| 770 | .index = target_symbol_index, | 769 | .index = target_symbol_index, |
| ... | @@ -964,7 +963,7 @@ pub fn freeDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool | ... | @@ -964,7 +963,7 @@ pub fn freeDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool |
| 964 | if (sym.isGlobal()) { | 963 | if (sym.isGlobal()) { |
| 965 | std.debug.assert(zig_object.global_syms.remove(atom.sym_index)); | 964 | std.debug.assert(zig_object.global_syms.remove(atom.sym_index)); |
| 966 | } | 965 | } |
| 967 | switch (decl.ty.zigTypeTag(mod)) { | 966 | switch (decl.typeOf(mod).zigTypeTag(mod)) { |
| 968 | .Fn => { | 967 | .Fn => { |
| 969 | zig_object.functions_free_list.append(gpa, sym.index) catch {}; | 968 | zig_object.functions_free_list.append(gpa, sym.index) catch {}; |
| 970 | std.debug.assert(zig_object.atom_types.remove(atom_index)); | 969 | std.debug.assert(zig_object.atom_types.remove(atom_index)); |
| ... | @@ -1242,7 +1241,6 @@ const Module = @import("../../Module.zig"); | ... | @@ -1242,7 +1241,6 @@ const Module = @import("../../Module.zig"); |
| 1242 | const StringTable = @import("../StringTable.zig"); | 1241 | const StringTable = @import("../StringTable.zig"); |
| 1243 | const Symbol = @import("Symbol.zig"); | 1242 | const Symbol = @import("Symbol.zig"); |
| 1244 | const Type = @import("../../type.zig").Type; | 1243 | const Type = @import("../../type.zig").Type; |
| 1245 | const TypedValue = @import("../../TypedValue.zig"); | ||
| 1246 | const Value = @import("../../Value.zig"); | 1244 | const Value = @import("../../Value.zig"); |
| 1247 | const Wasm = @import("../Wasm.zig"); | 1245 | const Wasm = @import("../Wasm.zig"); |
| 1248 | const ZigObject = @This(); | 1246 | const ZigObject = @This(); |
src/mutable_value.zig created+508| ... | @@ -0,0 +1,508 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const assert = std.debug.assert; | ||
| 3 | const Allocator = std.mem.Allocator; | ||
| 4 | const Zcu = @import("Module.zig"); | ||
| 5 | const InternPool = @import("InternPool.zig"); | ||
| 6 | const Type = @import("type.zig").Type; | ||
| 7 | const Value = @import("Value.zig"); | ||
| 8 | |||
| 9 | /// We use a tagged union here because while it wastes a few bytes for some tags, having a fixed | ||
| 10 | /// size for the type makes the common `aggregate` representation more efficient. | ||
| 11 | /// For aggregates, the sentinel value, if any, *is* stored. | ||
| 12 | pub const MutableValue = union(enum) { | ||
| 13 | /// An interned value. | ||
| 14 | interned: InternPool.Index, | ||
| 15 | /// An error union value which is a payload (not an error). | ||
| 16 | eu_payload: SubValue, | ||
| 17 | /// An optional value which is a payload (not `null`). | ||
| 18 | opt_payload: SubValue, | ||
| 19 | /// An aggregate consisting of a single repeated value. | ||
| 20 | repeated: SubValue, | ||
| 21 | /// An aggregate of `u8` consisting of "plain" bytes (no lazy or undefined elements). | ||
| 22 | bytes: Bytes, | ||
| 23 | /// An aggregate with arbitrary sub-values. | ||
| 24 | aggregate: Aggregate, | ||
| 25 | /// A slice, containing a pointer and length. | ||
| 26 | slice: Slice, | ||
| 27 | /// An instance of a union. | ||
| 28 | un: Union, | ||
| 29 | |||
| 30 | pub const SubValue = struct { | ||
| 31 | ty: InternPool.Index, | ||
| 32 | child: *MutableValue, | ||
| 33 | }; | ||
| 34 | pub const Bytes = struct { | ||
| 35 | ty: InternPool.Index, | ||
| 36 | data: []u8, | ||
| 37 | }; | ||
| 38 | pub const Aggregate = struct { | ||
| 39 | ty: InternPool.Index, | ||
| 40 | elems: []MutableValue, | ||
| 41 | }; | ||
| 42 | pub const Slice = struct { | ||
| 43 | ty: InternPool.Index, | ||
| 44 | /// Must have the appropriate many-ptr type. | ||
| 45 | /// TODO: we want this to be an `InternPool.Index`, but `Sema.beginComptimePtrMutation` doesn't support it. | ||
| 46 | ptr: *MutableValue, | ||
| 47 | /// Must be of type `usize`. | ||
| 48 | /// TODO: we want this to be an `InternPool.Index`, but `Sema.beginComptimePtrMutation` doesn't support it. | ||
| 49 | len: *MutableValue, | ||
| 50 | }; | ||
| 51 | pub const Union = struct { | ||
| 52 | ty: InternPool.Index, | ||
| 53 | tag: InternPool.Index, | ||
| 54 | payload: *MutableValue, | ||
| 55 | }; | ||
| 56 | |||
| 57 | pub fn intern(mv: MutableValue, zcu: *Zcu, arena: Allocator) Allocator.Error!InternPool.Index { | ||
| 58 | const ip = &zcu.intern_pool; | ||
| 59 | const gpa = zcu.gpa; | ||
| 60 | return switch (mv) { | ||
| 61 | .interned => |ip_index| ip_index, | ||
| 62 | .eu_payload => |sv| try ip.get(gpa, .{ .error_union = .{ | ||
| 63 | .ty = sv.ty, | ||
| 64 | .val = .{ .payload = try sv.child.intern(zcu, arena) }, | ||
| 65 | } }), | ||
| 66 | .opt_payload => |sv| try ip.get(gpa, .{ .opt = .{ | ||
| 67 | .ty = sv.ty, | ||
| 68 | .val = try sv.child.intern(zcu, arena), | ||
| 69 | } }), | ||
| 70 | .repeated => |sv| try ip.get(gpa, .{ .aggregate = .{ | ||
| 71 | .ty = sv.ty, | ||
| 72 | .storage = .{ .repeated_elem = try sv.child.intern(zcu, arena) }, | ||
| 73 | } }), | ||
| 74 | .bytes => |b| try ip.get(gpa, .{ .aggregate = .{ | ||
| 75 | .ty = b.ty, | ||
| 76 | .storage = .{ .bytes = b.data }, | ||
| 77 | } }), | ||
| 78 | .aggregate => |a| { | ||
| 79 | const elems = try arena.alloc(InternPool.Index, a.elems.len); | ||
| 80 | for (a.elems, elems) |mut_elem, *interned_elem| { | ||
| 81 | interned_elem.* = try mut_elem.intern(zcu, arena); | ||
| 82 | } | ||
| 83 | return ip.get(gpa, .{ .aggregate = .{ | ||
| 84 | .ty = a.ty, | ||
| 85 | .storage = .{ .elems = elems }, | ||
| 86 | } }); | ||
| 87 | }, | ||
| 88 | .slice => |s| try ip.get(gpa, .{ .slice = .{ | ||
| 89 | .ty = s.ty, | ||
| 90 | .ptr = try s.ptr.intern(zcu, arena), | ||
| 91 | .len = try s.len.intern(zcu, arena), | ||
| 92 | } }), | ||
| 93 | .un => |u| try ip.get(gpa, .{ .un = .{ | ||
| 94 | .ty = u.ty, | ||
| 95 | .tag = u.tag, | ||
| 96 | .val = try u.payload.intern(zcu, arena), | ||
| 97 | } }), | ||
| 98 | }; | ||
| 99 | } | ||
| 100 | |||
| 101 | /// Un-interns the top level of this `MutableValue`, if applicable. | ||
| 102 | /// * Non-error error unions use `eu_payload` | ||
| 103 | /// * Non-null optionals use `eu_payload | ||
| 104 | /// * Slices use `slice` | ||
| 105 | /// * Unions use `un` | ||
| 106 | /// * Aggregates use `repeated` or `bytes` or `aggregate` | ||
| 107 | /// If `!allow_bytes`, the `bytes` representation will not be used. | ||
| 108 | /// If `!allow_repeated`, the `repeated` representation will not be used. | ||
| 109 | pub fn unintern( | ||
| 110 | mv: *MutableValue, | ||
| 111 | zcu: *Zcu, | ||
| 112 | arena: Allocator, | ||
| 113 | allow_bytes: bool, | ||
| 114 | allow_repeated: bool, | ||
| 115 | ) Allocator.Error!void { | ||
| 116 | const ip = &zcu.intern_pool; | ||
| 117 | const gpa = zcu.gpa; | ||
| 118 | switch (mv.*) { | ||
| 119 | .interned => |ip_index| switch (ip.indexToKey(ip_index)) { | ||
| 120 | .opt => |opt| if (opt.val != .none) { | ||
| 121 | const mut_payload = try arena.create(MutableValue); | ||
| 122 | mut_payload.* = .{ .interned = opt.val }; | ||
| 123 | mv.* = .{ .opt_payload = .{ | ||
| 124 | .ty = opt.ty, | ||
| 125 | .child = mut_payload, | ||
| 126 | } }; | ||
| 127 | }, | ||
| 128 | .error_union => |eu| switch (eu.val) { | ||
| 129 | .err_name => {}, | ||
| 130 | .payload => |payload| { | ||
| 131 | const mut_payload = try arena.create(MutableValue); | ||
| 132 | mut_payload.* = .{ .interned = payload }; | ||
| 133 | mv.* = .{ .eu_payload = .{ | ||
| 134 | .ty = eu.ty, | ||
| 135 | .child = mut_payload, | ||
| 136 | } }; | ||
| 137 | }, | ||
| 138 | }, | ||
| 139 | .slice => |slice| { | ||
| 140 | const ptr = try arena.create(MutableValue); | ||
| 141 | const len = try arena.create(MutableValue); | ||
| 142 | ptr.* = .{ .interned = slice.ptr }; | ||
| 143 | len.* = .{ .interned = slice.len }; | ||
| 144 | mv.* = .{ .slice = .{ | ||
| 145 | .ty = slice.ty, | ||
| 146 | .ptr = ptr, | ||
| 147 | .len = len, | ||
| 148 | } }; | ||
| 149 | }, | ||
| 150 | .un => |un| { | ||
| 151 | const payload = try arena.create(MutableValue); | ||
| 152 | payload.* = .{ .interned = un.val }; | ||
| 153 | mv.* = .{ .un = .{ | ||
| 154 | .ty = un.ty, | ||
| 155 | .tag = un.tag, | ||
| 156 | .payload = payload, | ||
| 157 | } }; | ||
| 158 | }, | ||
| 159 | .aggregate => |agg| switch (agg.storage) { | ||
| 160 | .bytes => |bytes| { | ||
| 161 | assert(bytes.len == ip.aggregateTypeLenIncludingSentinel(agg.ty)); | ||
| 162 | assert(ip.childType(agg.ty) == .u8_type); | ||
| 163 | if (allow_bytes) { | ||
| 164 | const arena_bytes = try arena.alloc(u8, bytes.len); | ||
| 165 | @memcpy(arena_bytes, bytes); | ||
| 166 | mv.* = .{ .bytes = .{ | ||
| 167 | .ty = agg.ty, | ||
| 168 | .data = arena_bytes, | ||
| 169 | } }; | ||
| 170 | } else { | ||
| 171 | const mut_elems = try arena.alloc(MutableValue, bytes.len); | ||
| 172 | for (bytes, mut_elems) |b, *mut_elem| { | ||
| 173 | mut_elem.* = .{ .interned = try ip.get(gpa, .{ .int = .{ | ||
| 174 | .ty = .u8_type, | ||
| 175 | .storage = .{ .u64 = b }, | ||
| 176 | } }) }; | ||
| 177 | } | ||
| 178 | mv.* = .{ .aggregate = .{ | ||
| 179 | .ty = agg.ty, | ||
| 180 | .elems = mut_elems, | ||
| 181 | } }; | ||
| 182 | } | ||
| 183 | }, | ||
| 184 | .elems => |elems| { | ||
| 185 | assert(elems.len == ip.aggregateTypeLenIncludingSentinel(agg.ty)); | ||
| 186 | const mut_elems = try arena.alloc(MutableValue, elems.len); | ||
| 187 | for (elems, mut_elems) |interned_elem, *mut_elem| { | ||
| 188 | mut_elem.* = .{ .interned = interned_elem }; | ||
| 189 | } | ||
| 190 | mv.* = .{ .aggregate = .{ | ||
| 191 | .ty = agg.ty, | ||
| 192 | .elems = mut_elems, | ||
| 193 | } }; | ||
| 194 | }, | ||
| 195 | .repeated_elem => |val| { | ||
| 196 | if (allow_repeated) { | ||
| 197 | const repeated_val = try arena.create(MutableValue); | ||
| 198 | repeated_val.* = .{ .interned = val }; | ||
| 199 | mv.* = .{ .repeated = .{ | ||
| 200 | .ty = agg.ty, | ||
| 201 | .child = repeated_val, | ||
| 202 | } }; | ||
| 203 | } else { | ||
| 204 | const len = ip.aggregateTypeLenIncludingSentinel(agg.ty); | ||
| 205 | const mut_elems = try arena.alloc(MutableValue, @intCast(len)); | ||
| 206 | @memset(mut_elems, .{ .interned = val }); | ||
| 207 | mv.* = .{ .aggregate = .{ | ||
| 208 | .ty = agg.ty, | ||
| 209 | .elems = mut_elems, | ||
| 210 | } }; | ||
| 211 | } | ||
| 212 | }, | ||
| 213 | }, | ||
| 214 | .undef => |ty_ip| switch (Type.fromInterned(ty_ip).zigTypeTag(zcu)) { | ||
| 215 | .Struct, .Array, .Vector => |type_tag| { | ||
| 216 | const ty = Type.fromInterned(ty_ip); | ||
| 217 | const opt_sent = ty.sentinel(zcu); | ||
| 218 | if (type_tag == .Struct or opt_sent != null or !allow_repeated) { | ||
| 219 | const len_no_sent = ip.aggregateTypeLen(ty_ip); | ||
| 220 | const elems = try arena.alloc(MutableValue, @intCast(len_no_sent + @intFromBool(opt_sent != null))); | ||
| 221 | switch (type_tag) { | ||
| 222 | .Array, .Vector => { | ||
| 223 | const elem_ty = ip.childType(ty_ip); | ||
| 224 | const undef_elem = try ip.get(gpa, .{ .undef = elem_ty }); | ||
| 225 | @memset(elems[0..@intCast(len_no_sent)], .{ .interned = undef_elem }); | ||
| 226 | }, | ||
| 227 | .Struct => for (elems[0..@intCast(len_no_sent)], 0..) |*mut_elem, i| { | ||
| 228 | const field_ty = ty.structFieldType(i, zcu).toIntern(); | ||
| 229 | mut_elem.* = .{ .interned = try ip.get(gpa, .{ .undef = field_ty }) }; | ||
| 230 | }, | ||
| 231 | else => unreachable, | ||
| 232 | } | ||
| 233 | if (opt_sent) |s| elems[@intCast(len_no_sent)] = .{ .interned = s.toIntern() }; | ||
| 234 | mv.* = .{ .aggregate = .{ | ||
| 235 | .ty = ty_ip, | ||
| 236 | .elems = elems, | ||
| 237 | } }; | ||
| 238 | } else { | ||
| 239 | const repeated_val = try arena.create(MutableValue); | ||
| 240 | repeated_val.* = .{ | ||
| 241 | .interned = try ip.get(gpa, .{ .undef = ip.childType(ty_ip) }), | ||
| 242 | }; | ||
| 243 | mv.* = .{ .repeated = .{ | ||
| 244 | .ty = ty_ip, | ||
| 245 | .child = repeated_val, | ||
| 246 | } }; | ||
| 247 | } | ||
| 248 | }, | ||
| 249 | .Union => { | ||
| 250 | const payload = try arena.create(MutableValue); | ||
| 251 | // HACKHACK: this logic is silly, but Sema detects it and reverts the change where needed. | ||
| 252 | // See comment at the top of `Sema.beginComptimePtrMutationInner`. | ||
| 253 | payload.* = .{ .interned = .undef }; | ||
| 254 | mv.* = .{ .un = .{ | ||
| 255 | .ty = ty_ip, | ||
| 256 | .tag = .none, | ||
| 257 | .payload = payload, | ||
| 258 | } }; | ||
| 259 | }, | ||
| 260 | .Pointer => { | ||
| 261 | const ptr_ty = ip.indexToKey(ty_ip).ptr_type; | ||
| 262 | if (ptr_ty.flags.size != .Slice) return; | ||
| 263 | const ptr = try arena.create(MutableValue); | ||
| 264 | const len = try arena.create(MutableValue); | ||
| 265 | ptr.* = .{ .interned = try ip.get(gpa, .{ .undef = ip.slicePtrType(ty_ip) }) }; | ||
| 266 | len.* = .{ .interned = try ip.get(gpa, .{ .undef = .usize_type }) }; | ||
| 267 | mv.* = .{ .slice = .{ | ||
| 268 | .ty = ty_ip, | ||
| 269 | .ptr = ptr, | ||
| 270 | .len = len, | ||
| 271 | } }; | ||
| 272 | }, | ||
| 273 | else => {}, | ||
| 274 | }, | ||
| 275 | else => {}, | ||
| 276 | }, | ||
| 277 | .bytes => |bytes| if (!allow_bytes) { | ||
| 278 | const elems = try arena.alloc(MutableValue, bytes.data.len); | ||
| 279 | for (bytes.data, elems) |byte, *interned_byte| { | ||
| 280 | interned_byte.* = .{ .interned = try ip.get(gpa, .{ .int = .{ | ||
| 281 | .ty = .u8_type, | ||
| 282 | .storage = .{ .u64 = byte }, | ||
| 283 | } }) }; | ||
| 284 | } | ||
| 285 | mv.* = .{ .aggregate = .{ | ||
| 286 | .ty = bytes.ty, | ||
| 287 | .elems = elems, | ||
| 288 | } }; | ||
| 289 | }, | ||
| 290 | else => {}, | ||
| 291 | } | ||
| 292 | } | ||
| 293 | |||
| 294 | /// Get a pointer to the `MutableValue` associated with a field/element. | ||
| 295 | /// The returned pointer can be safety mutated through to modify the field value. | ||
| 296 | /// The returned pointer is valid until the representation of `mv` changes. | ||
| 297 | /// This function does *not* support accessing the ptr/len field of slices. | ||
| 298 | pub fn elem( | ||
| 299 | mv: *MutableValue, | ||
| 300 | zcu: *Zcu, | ||
| 301 | arena: Allocator, | ||
| 302 | field_idx: usize, | ||
| 303 | ) Allocator.Error!*MutableValue { | ||
| 304 | const ip = &zcu.intern_pool; | ||
| 305 | const gpa = zcu.gpa; | ||
| 306 | // Convert to the `aggregate` representation. | ||
| 307 | switch (mv) { | ||
| 308 | .eu_payload, .opt_payload, .slice, .un => unreachable, | ||
| 309 | .interned => { | ||
| 310 | try mv.unintern(zcu, arena, false, false); | ||
| 311 | }, | ||
| 312 | .bytes => |bytes| { | ||
| 313 | const elems = try arena.alloc(MutableValue, bytes.data.len); | ||
| 314 | for (bytes.data, elems) |byte, interned_byte| { | ||
| 315 | interned_byte.* = try ip.get(gpa, .{ .int = .{ | ||
| 316 | .ty = .u8_type, | ||
| 317 | .storage = .{ .u64 = byte }, | ||
| 318 | } }); | ||
| 319 | } | ||
| 320 | mv.* = .{ .aggregate = .{ | ||
| 321 | .ty = bytes.ty, | ||
| 322 | .elems = elems, | ||
| 323 | } }; | ||
| 324 | }, | ||
| 325 | .repeated => |repeated| { | ||
| 326 | const len = ip.aggregateTypeLenIncludingSentinel(repeated.ty); | ||
| 327 | const elems = try arena.alloc(MutableValue, @intCast(len)); | ||
| 328 | @memset(elems, repeated.child.*); | ||
| 329 | mv.* = .{ .aggregate = .{ | ||
| 330 | .ty = repeated.ty, | ||
| 331 | .elems = elems, | ||
| 332 | } }; | ||
| 333 | }, | ||
| 334 | .aggregate => {}, | ||
| 335 | } | ||
| 336 | return &mv.aggregate.elems[field_idx]; | ||
| 337 | } | ||
| 338 | |||
| 339 | /// Modify a single field of a `MutableValue` which represents an aggregate or slice, leaving others | ||
| 340 | /// untouched. When an entire field must be modified, this should be used in preference to `elemPtr` | ||
| 341 | /// to allow for an optimal representation. | ||
| 342 | /// For slices, uses `Value.slice_ptr_index` and `Value.slice_len_index`. | ||
| 343 | pub fn setElem( | ||
| 344 | mv: *MutableValue, | ||
| 345 | zcu: *Zcu, | ||
| 346 | arena: Allocator, | ||
| 347 | field_idx: usize, | ||
| 348 | field_val: MutableValue, | ||
| 349 | ) Allocator.Error!void { | ||
| 350 | const ip = &zcu.intern_pool; | ||
| 351 | const is_trivial_int = field_val.isTrivialInt(zcu); | ||
| 352 | try mv.unintern(arena, is_trivial_int, true); | ||
| 353 | switch (mv) { | ||
| 354 | .interned, | ||
| 355 | .eu_payload, | ||
| 356 | .opt_payload, | ||
| 357 | .un, | ||
| 358 | => unreachable, | ||
| 359 | .slice => |*s| switch (field_idx) { | ||
| 360 | Value.slice_ptr_index => s.ptr = field_val, | ||
| 361 | Value.slice_len_index => s.len = field_val, | ||
| 362 | }, | ||
| 363 | .bytes => |b| { | ||
| 364 | assert(is_trivial_int); | ||
| 365 | assert(field_val.typeOf() == Type.u8); | ||
| 366 | b.data[field_idx] = Value.fromInterned(field_val.interned).toUnsignedInt(zcu); | ||
| 367 | }, | ||
| 368 | .repeated => |r| { | ||
| 369 | if (field_val.eqlTrivial(r.child.*)) return; | ||
| 370 | // We must switch to either the `aggregate` or the `bytes` representation. | ||
| 371 | const len_inc_sent = ip.aggregateTypeLenIncludingSentinel(r.ty); | ||
| 372 | if (ip.zigTypeTag(r.ty) != .Struct and | ||
| 373 | is_trivial_int and | ||
| 374 | Type.fromInterned(r.ty).childType(zcu) == .u8_type and | ||
| 375 | r.child.isTrivialInt(zcu)) | ||
| 376 | { | ||
| 377 | // We can use the `bytes` representation. | ||
| 378 | const bytes = try arena.alloc(u8, @intCast(len_inc_sent)); | ||
| 379 | const repeated_byte = Value.fromInterned(r.child.interned).getUnsignedInt(zcu); | ||
| 380 | @memset(bytes, repeated_byte); | ||
| 381 | bytes[field_idx] = Value.fromInterned(field_val.interned).getUnsignedInt(zcu); | ||
| 382 | mv.* = .{ .bytes = .{ | ||
| 383 | .ty = r.ty, | ||
| 384 | .data = bytes, | ||
| 385 | } }; | ||
| 386 | } else { | ||
| 387 | // We must use the `aggregate` representation. | ||
| 388 | const mut_elems = try arena.alloc(u8, @intCast(len_inc_sent)); | ||
| 389 | @memset(mut_elems, r.child.*); | ||
| 390 | mut_elems[field_idx] = field_val; | ||
| 391 | mv.* = .{ .aggregate = .{ | ||
| 392 | .ty = r.ty, | ||
| 393 | .elems = mut_elems, | ||
| 394 | } }; | ||
| 395 | } | ||
| 396 | }, | ||
| 397 | .aggregate => |a| { | ||
| 398 | a.elems[field_idx] = field_val; | ||
| 399 | const is_struct = ip.zigTypeTag(a.ty) == .Struct; | ||
| 400 | // Attempt to switch to a more efficient representation. | ||
| 401 | const is_repeated = for (a.elems) |e| { | ||
| 402 | if (!e.eqlTrivial(field_val)) break false; | ||
| 403 | } else true; | ||
| 404 | if (is_repeated) { | ||
| 405 | // Switch to `repeated` repr | ||
| 406 | const mut_repeated = try arena.create(MutableValue); | ||
| 407 | mut_repeated.* = field_val; | ||
| 408 | mv.* = .{ .repeated = .{ | ||
| 409 | .ty = a.ty, | ||
| 410 | .child = mut_repeated, | ||
| 411 | } }; | ||
| 412 | } else if (!is_struct and is_trivial_int and Type.fromInterned(a.ty).childType(zcu).toIntern() == .u8_type) { | ||
| 413 | // See if we can switch to `bytes` repr | ||
| 414 | for (a.elems) |e| { | ||
| 415 | switch (e) { | ||
| 416 | else => break, | ||
| 417 | .interned => |ip_index| switch (ip.indexToKey(ip_index)) { | ||
| 418 | else => break, | ||
| 419 | .int => |int| switch (int.storage) { | ||
| 420 | .u64, .i64, .big_int => {}, | ||
| 421 | .lazy_align, .lazy_size => break, | ||
| 422 | }, | ||
| 423 | }, | ||
| 424 | } | ||
| 425 | } else { | ||
| 426 | const bytes = try arena.alloc(u8, a.elems.len); | ||
| 427 | for (a.elems, bytes) |elem_val, *b| { | ||
| 428 | b.* = Value.fromInterned(elem_val.interned).toUnsignedInt(zcu); | ||
| 429 | } | ||
| 430 | mv.* = .{ .bytes = .{ | ||
| 431 | .ty = a.ty, | ||
| 432 | .data = bytes, | ||
| 433 | } }; | ||
| 434 | } | ||
| 435 | } | ||
| 436 | }, | ||
| 437 | } | ||
| 438 | } | ||
| 439 | |||
| 440 | /// Get the value of a single field of a `MutableValue` which represents an aggregate or slice. | ||
| 441 | /// For slices, uses `Value.slice_ptr_index` and `Value.slice_len_index`. | ||
| 442 | pub fn getElem( | ||
| 443 | mv: MutableValue, | ||
| 444 | zcu: *Zcu, | ||
| 445 | field_idx: usize, | ||
| 446 | ) Allocator.Error!MutableValue { | ||
| 447 | return switch (mv) { | ||
| 448 | .eu_payload, | ||
| 449 | .opt_payload, | ||
| 450 | => unreachable, | ||
| 451 | .interned => |ip_index| { | ||
| 452 | const ty = Type.fromInterned(zcu.intern_pool.typeOf(ip_index)); | ||
| 453 | switch (ty.zigTypeTag(zcu)) { | ||
| 454 | .Array, .Vector => return .{ .interned = (try Value.fromInterned(ip_index).elemValue(zcu, field_idx)).toIntern() }, | ||
| 455 | .Struct, .Union => return .{ .interned = (try Value.fromInterned(ip_index).fieldValue(zcu, field_idx)).toIntern() }, | ||
| 456 | .Pointer => { | ||
| 457 | assert(ty.isSlice(zcu)); | ||
| 458 | return switch (field_idx) { | ||
| 459 | Value.slice_ptr_index => .{ .interned = Value.fromInterned(ip_index).slicePtr(zcu).toIntern() }, | ||
| 460 | Value.slice_len_index => .{ .interned = switch (zcu.intern_pool.indexToKey(ip_index)) { | ||
| 461 | .undef => try zcu.intern(.{ .undef = .usize_type }), | ||
| 462 | .slice => |s| s.len, | ||
| 463 | else => unreachable, | ||
| 464 | } }, | ||
| 465 | else => unreachable, | ||
| 466 | }; | ||
| 467 | }, | ||
| 468 | else => unreachable, | ||
| 469 | } | ||
| 470 | }, | ||
| 471 | .un => |un| { | ||
| 472 | // TODO assert the tag is correct | ||
| 473 | return un.payload.*; | ||
| 474 | }, | ||
| 475 | .slice => |s| switch (field_idx) { | ||
| 476 | Value.slice_ptr_index => s.ptr.*, | ||
| 477 | Value.slice_len_index => s.len.*, | ||
| 478 | else => unreachable, | ||
| 479 | }, | ||
| 480 | .bytes => |b| .{ .interned = try zcu.intern(.{ .int = .{ | ||
| 481 | .ty = .u8_type, | ||
| 482 | .storage = .{ .u64 = b.data[field_idx] }, | ||
| 483 | } }) }, | ||
| 484 | .repeated => |r| r.child.*, | ||
| 485 | .aggregate => |a| a.elems[field_idx], | ||
| 486 | }; | ||
| 487 | } | ||
| 488 | |||
| 489 | fn isTrivialInt(mv: MutableValue, zcu: *Zcu) bool { | ||
| 490 | return switch (mv) { | ||
| 491 | else => false, | ||
| 492 | .interned => |ip_index| switch (zcu.intern_pool.indexToKey(ip_index)) { | ||
| 493 | else => false, | ||
| 494 | .int => |int| switch (int.storage) { | ||
| 495 | .u64, .i64, .big_int => true, | ||
| 496 | .lazy_align, .lazy_size => false, | ||
| 497 | }, | ||
| 498 | }, | ||
| 499 | }; | ||
| 500 | } | ||
| 501 | |||
| 502 | pub fn typeOf(mv: MutableValue, zcu: *Zcu) Type { | ||
| 503 | return switch (mv) { | ||
| 504 | .interned => |ip_index| Type.fromInterned(zcu.intern_pool.typeOf(ip_index)), | ||
| 505 | inline else => |x| Type.fromInterned(x.ty), | ||
| 506 | }; | ||
| 507 | } | ||
| 508 | }; | ||
src/print_air.zig+1-1| ... | @@ -951,7 +951,7 @@ const Writer = struct { | ... | @@ -951,7 +951,7 @@ const Writer = struct { |
| 951 | const ty = Type.fromInterned(mod.intern_pool.indexToKey(ip_index).typeOf()); | 951 | const ty = Type.fromInterned(mod.intern_pool.indexToKey(ip_index).typeOf()); |
| 952 | try s.print("<{}, {}>", .{ | 952 | try s.print("<{}, {}>", .{ |
| 953 | ty.fmt(mod), | 953 | ty.fmt(mod), |
| 954 | Value.fromInterned(ip_index).fmtValue(ty, mod), | 954 | Value.fromInterned(ip_index).fmtValue(mod), |
| 955 | }); | 955 | }); |
| 956 | } else { | 956 | } else { |
| 957 | return w.writeInstIndex(s, operand.toIndex().?, dies); | 957 | return w.writeInstIndex(s, operand.toIndex().?, dies); |
src/print_value.zig created+354| ... | @@ -0,0 +1,354 @@ | ||
| 1 | //! This type exists only for legacy purposes, and will be removed in the future. | ||
| 2 | //! It is a thin wrapper around a `Value` which also, redundantly, stores its `Type`. | ||
| 3 | |||
| 4 | const std = @import("std"); | ||
| 5 | const Type = @import("type.zig").Type; | ||
| 6 | const Value = @import("Value.zig"); | ||
| 7 | const Zcu = @import("Module.zig"); | ||
| 8 | const Module = Zcu; | ||
| 9 | const Sema = @import("Sema.zig"); | ||
| 10 | const InternPool = @import("InternPool.zig"); | ||
| 11 | const Allocator = std.mem.Allocator; | ||
| 12 | const Target = std.Target; | ||
| 13 | |||
| 14 | const max_aggregate_items = 100; | ||
| 15 | const max_string_len = 256; | ||
| 16 | |||
| 17 | const FormatContext = struct { | ||
| 18 | val: Value, | ||
| 19 | mod: *Module, | ||
| 20 | }; | ||
| 21 | |||
| 22 | pub fn format( | ||
| 23 | ctx: FormatContext, | ||
| 24 | comptime fmt: []const u8, | ||
| 25 | options: std.fmt.FormatOptions, | ||
| 26 | writer: anytype, | ||
| 27 | ) !void { | ||
| 28 | _ = options; | ||
| 29 | comptime std.debug.assert(fmt.len == 0); | ||
| 30 | return print(ctx.val, writer, 3, ctx.mod, null) catch |err| switch (err) { | ||
| 31 | error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function | ||
| 32 | error.ComptimeBreak, error.ComptimeReturn => unreachable, | ||
| 33 | error.AnalysisFail, error.NeededSourceLocation => unreachable, // TODO: re-evaluate when we actually pass `opt_sema` | ||
| 34 | else => |e| return e, | ||
| 35 | }; | ||
| 36 | } | ||
| 37 | |||
| 38 | pub fn print( | ||
| 39 | val: Value, | ||
| 40 | writer: anytype, | ||
| 41 | level: u8, | ||
| 42 | mod: *Module, | ||
| 43 | /// If this `Sema` is provided, we will recurse through pointers where possible to provide friendly output. | ||
| 44 | opt_sema: ?*Sema, | ||
| 45 | ) (@TypeOf(writer).Error || Module.CompileError)!void { | ||
| 46 | const ip = &mod.intern_pool; | ||
| 47 | switch (ip.indexToKey(val.toIntern())) { | ||
| 48 | .int_type, | ||
| 49 | .ptr_type, | ||
| 50 | .array_type, | ||
| 51 | .vector_type, | ||
| 52 | .opt_type, | ||
| 53 | .anyframe_type, | ||
| 54 | .error_union_type, | ||
| 55 | .simple_type, | ||
| 56 | .struct_type, | ||
| 57 | .anon_struct_type, | ||
| 58 | .union_type, | ||
| 59 | .opaque_type, | ||
| 60 | .enum_type, | ||
| 61 | .func_type, | ||
| 62 | .error_set_type, | ||
| 63 | .inferred_error_set_type, | ||
| 64 | => try Type.print(val.toType(), writer, mod), | ||
| 65 | .undef => try writer.writeAll("undefined"), | ||
| 66 | .simple_value => |simple_value| switch (simple_value) { | ||
| 67 | .void => try writer.writeAll("{}"), | ||
| 68 | .empty_struct => try writer.writeAll(".{}"), | ||
| 69 | .generic_poison => try writer.writeAll("(generic poison)"), | ||
| 70 | else => try writer.writeAll(@tagName(simple_value)), | ||
| 71 | }, | ||
| 72 | .variable => try writer.writeAll("(variable)"), | ||
| 73 | .extern_func => |extern_func| try writer.print("(extern function '{}')", .{ | ||
| 74 | mod.declPtr(extern_func.decl).name.fmt(ip), | ||
| 75 | }), | ||
| 76 | .func => |func| try writer.print("(function '{}')", .{ | ||
| 77 | mod.declPtr(func.owner_decl).name.fmt(ip), | ||
| 78 | }), | ||
| 79 | .int => |int| switch (int.storage) { | ||
| 80 | inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}), | ||
| 81 | .lazy_align => |ty| if (opt_sema) |sema| { | ||
| 82 | const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar; | ||
| 83 | try writer.print("{}", .{a.toByteUnits(0)}); | ||
| 84 | } else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(mod)}), | ||
| 85 | .lazy_size => |ty| if (opt_sema) |sema| { | ||
| 86 | const s = (try Type.fromInterned(ty).abiSizeAdvanced(mod, .{ .sema = sema })).scalar; | ||
| 87 | try writer.print("{}", .{s}); | ||
| 88 | } else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(mod)}), | ||
| 89 | }, | ||
| 90 | .err => |err| try writer.print("error.{}", .{ | ||
| 91 | err.name.fmt(ip), | ||
| 92 | }), | ||
| 93 | .error_union => |error_union| switch (error_union.val) { | ||
| 94 | .err_name => |err_name| try writer.print("error.{}", .{ | ||
| 95 | err_name.fmt(ip), | ||
| 96 | }), | ||
| 97 | .payload => |payload| try print(Value.fromInterned(payload), writer, level, mod, opt_sema), | ||
| 98 | }, | ||
| 99 | .enum_literal => |enum_literal| try writer.print(".{}", .{ | ||
| 100 | enum_literal.fmt(ip), | ||
| 101 | }), | ||
| 102 | .enum_tag => |enum_tag| { | ||
| 103 | const enum_type = ip.loadEnumType(val.typeOf(mod).toIntern()); | ||
| 104 | if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| { | ||
| 105 | return writer.print(".{i}", .{enum_type.names.get(ip)[tag_index].fmt(ip)}); | ||
| 106 | } | ||
| 107 | if (level == 0) { | ||
| 108 | return writer.writeAll("@enumFromInt(...)"); | ||
| 109 | } | ||
| 110 | try writer.writeAll("@enumFromInt("); | ||
| 111 | try print(Value.fromInterned(enum_tag.int), writer, level - 1, mod, opt_sema); | ||
| 112 | try writer.writeAll(")"); | ||
| 113 | }, | ||
| 114 | .empty_enum_value => try writer.writeAll("(empty enum value)"), | ||
| 115 | .float => |float| switch (float.storage) { | ||
| 116 | inline else => |x| try writer.print("{d}", .{@as(f64, @floatCast(x))}), | ||
| 117 | }, | ||
| 118 | .slice => |slice| { | ||
| 119 | const print_contents = switch (ip.getBackingAddrTag(slice.ptr).?) { | ||
| 120 | .field, .elem, .eu_payload, .opt_payload => unreachable, | ||
| 121 | .anon_decl, .comptime_alloc, .comptime_field => true, | ||
| 122 | .decl, .int => false, | ||
| 123 | }; | ||
| 124 | if (print_contents) { | ||
| 125 | // TODO: eventually we want to load the slice as an array with `opt_sema`, but that's | ||
| 126 | // currently not possible without e.g. triggering compile errors. | ||
| 127 | } | ||
| 128 | try printPtr(slice.ptr, writer, false, false, 0, level, mod, opt_sema); | ||
| 129 | try writer.writeAll("[0.."); | ||
| 130 | if (level == 0) { | ||
| 131 | try writer.writeAll("(...)"); | ||
| 132 | } else { | ||
| 133 | try print(Value.fromInterned(slice.len), writer, level - 1, mod, opt_sema); | ||
| 134 | } | ||
| 135 | try writer.writeAll("]"); | ||
| 136 | }, | ||
| 137 | .ptr => { | ||
| 138 | const print_contents = switch (ip.getBackingAddrTag(val.toIntern()).?) { | ||
| 139 | .field, .elem, .eu_payload, .opt_payload => unreachable, | ||
| 140 | .anon_decl, .comptime_alloc, .comptime_field => true, | ||
| 141 | .decl, .int => false, | ||
| 142 | }; | ||
| 143 | if (print_contents) { | ||
| 144 | // TODO: eventually we want to load the pointer with `opt_sema`, but that's | ||
| 145 | // currently not possible without e.g. triggering compile errors. | ||
| 146 | } | ||
| 147 | try printPtr(val.toIntern(), writer, false, false, 0, level, mod, opt_sema); | ||
| 148 | }, | ||
| 149 | .opt => |opt| switch (opt.val) { | ||
| 150 | .none => try writer.writeAll("null"), | ||
| 151 | else => |payload| try print(Value.fromInterned(payload), writer, level, mod, opt_sema), | ||
| 152 | }, | ||
| 153 | .aggregate => |aggregate| try printAggregate(val, aggregate, writer, level, false, mod, opt_sema), | ||
| 154 | .un => |un| { | ||
| 155 | if (level == 0) { | ||
| 156 | try writer.writeAll(".{ ... }"); | ||
| 157 | return; | ||
| 158 | } | ||
| 159 | if (un.tag == .none) { | ||
| 160 | const backing_ty = try val.typeOf(mod).unionBackingType(mod); | ||
| 161 | try writer.print("@bitCast(@as({}, ", .{backing_ty.fmt(mod)}); | ||
| 162 | try print(Value.fromInterned(un.val), writer, level - 1, mod, opt_sema); | ||
| 163 | try writer.writeAll("))"); | ||
| 164 | } else { | ||
| 165 | try writer.writeAll(".{ "); | ||
| 166 | try print(Value.fromInterned(un.tag), writer, level - 1, mod, opt_sema); | ||
| 167 | try writer.writeAll(" = "); | ||
| 168 | try print(Value.fromInterned(un.val), writer, level - 1, mod, opt_sema); | ||
| 169 | try writer.writeAll(" }"); | ||
| 170 | } | ||
| 171 | }, | ||
| 172 | .memoized_call => unreachable, | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | fn printAggregate( | ||
| 177 | val: Value, | ||
| 178 | aggregate: InternPool.Key.Aggregate, | ||
| 179 | writer: anytype, | ||
| 180 | level: u8, | ||
| 181 | is_ref: bool, | ||
| 182 | zcu: *Zcu, | ||
| 183 | opt_sema: ?*Sema, | ||
| 184 | ) (@TypeOf(writer).Error || Module.CompileError)!void { | ||
| 185 | if (level == 0) { | ||
| 186 | return writer.writeAll(".{ ... }"); | ||
| 187 | } | ||
| 188 | const ip = &zcu.intern_pool; | ||
| 189 | const ty = Type.fromInterned(aggregate.ty); | ||
| 190 | switch (ty.zigTypeTag(zcu)) { | ||
| 191 | .Struct => if (!ty.isTuple(zcu)) { | ||
| 192 | if (is_ref) try writer.writeByte('&'); | ||
| 193 | if (ty.structFieldCount(zcu) == 0) { | ||
| 194 | return writer.writeAll(".{}"); | ||
| 195 | } | ||
| 196 | try writer.writeAll(".{ "); | ||
| 197 | const max_len = @min(ty.structFieldCount(zcu), max_aggregate_items); | ||
| 198 | for (0..max_len) |i| { | ||
| 199 | if (i != 0) try writer.writeAll(", "); | ||
| 200 | const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?; | ||
| 201 | try writer.print(".{i} = ", .{field_name.fmt(ip)}); | ||
| 202 | try print(try val.fieldValue(zcu, i), writer, level - 1, zcu, opt_sema); | ||
| 203 | } | ||
| 204 | try writer.writeAll(" }"); | ||
| 205 | return; | ||
| 206 | }, | ||
| 207 | .Array => if (aggregate.storage == .bytes and aggregate.storage.bytes.len > 0) { | ||
| 208 | const skip_terminator = aggregate.storage.bytes[aggregate.storage.bytes.len - 1] == 0; | ||
| 209 | const bytes = if (skip_terminator) b: { | ||
| 210 | break :b aggregate.storage.bytes[0 .. aggregate.storage.bytes.len - 1]; | ||
| 211 | } else aggregate.storage.bytes; | ||
| 212 | try writer.print("\"{}\"", .{std.zig.fmtEscapes(bytes)}); | ||
| 213 | if (!is_ref) try writer.writeAll(".*"); | ||
| 214 | return; | ||
| 215 | } else if (ty.arrayLen(zcu) == 0) { | ||
| 216 | if (is_ref) try writer.writeByte('&'); | ||
| 217 | return writer.writeAll(".{}"); | ||
| 218 | } else if (ty.arrayLen(zcu) == 1) one_byte_str: { | ||
| 219 | // The repr isn't `bytes`, but we might still be able to print this as a string | ||
| 220 | if (ty.childType(zcu).toIntern() != .u8_type) break :one_byte_str; | ||
| 221 | const elem_val = Value.fromInterned(aggregate.storage.values()[0]); | ||
| 222 | if (elem_val.isUndef(zcu)) break :one_byte_str; | ||
| 223 | const byte = elem_val.toUnsignedInt(zcu); | ||
| 224 | try writer.print("\"{}\"", .{std.zig.fmtEscapes(&.{@intCast(byte)})}); | ||
| 225 | if (!is_ref) try writer.writeAll(".*"); | ||
| 226 | return; | ||
| 227 | }, | ||
| 228 | .Vector => if (ty.arrayLen(zcu) == 0) { | ||
| 229 | if (is_ref) try writer.writeByte('&'); | ||
| 230 | return writer.writeAll(".{}"); | ||
| 231 | }, | ||
| 232 | else => unreachable, | ||
| 233 | } | ||
| 234 | |||
| 235 | const len = ty.arrayLen(zcu); | ||
| 236 | |||
| 237 | if (is_ref) try writer.writeByte('&'); | ||
| 238 | try writer.writeAll(".{ "); | ||
| 239 | |||
| 240 | const max_len = @min(len, max_aggregate_items); | ||
| 241 | for (0..max_len) |i| { | ||
| 242 | if (i != 0) try writer.writeAll(", "); | ||
| 243 | try print(try val.fieldValue(zcu, i), writer, level - 1, zcu, opt_sema); | ||
| 244 | } | ||
| 245 | if (len > max_aggregate_items) { | ||
| 246 | try writer.writeAll(", ..."); | ||
| 247 | } | ||
| 248 | return writer.writeAll(" }"); | ||
| 249 | } | ||
| 250 | |||
| 251 | fn printPtr( | ||
| 252 | ptr_val: InternPool.Index, | ||
| 253 | writer: anytype, | ||
| 254 | force_type: bool, | ||
| 255 | force_addrof: bool, | ||
| 256 | leading_parens: u32, | ||
| 257 | level: u8, | ||
| 258 | zcu: *Zcu, | ||
| 259 | opt_sema: ?*Sema, | ||
| 260 | ) (@TypeOf(writer).Error || Module.CompileError)!void { | ||
| 261 | const ip = &zcu.intern_pool; | ||
| 262 | const ptr = switch (ip.indexToKey(ptr_val)) { | ||
| 263 | .undef => |ptr_ty| { | ||
| 264 | if (force_addrof) try writer.writeAll("&"); | ||
| 265 | try writer.writeByteNTimes('(', leading_parens); | ||
| 266 | try writer.print("@as({}, undefined)", .{Type.fromInterned(ptr_ty).fmt(zcu)}); | ||
| 267 | return; | ||
| 268 | }, | ||
| 269 | .ptr => |ptr| ptr, | ||
| 270 | else => unreachable, | ||
| 271 | }; | ||
| 272 | if (level == 0) { | ||
| 273 | return writer.writeAll("&..."); | ||
| 274 | } | ||
| 275 | switch (ptr.addr) { | ||
| 276 | .int => |int| { | ||
| 277 | if (force_addrof) try writer.writeAll("&"); | ||
| 278 | try writer.writeByteNTimes('(', leading_parens); | ||
| 279 | if (force_type) { | ||
| 280 | try writer.print("@as({}, @ptrFromInt(", .{Type.fromInterned(ptr.ty).fmt(zcu)}); | ||
| 281 | try print(Value.fromInterned(int), writer, level - 1, zcu, opt_sema); | ||
| 282 | try writer.writeAll("))"); | ||
| 283 | } else { | ||
| 284 | try writer.writeAll("@ptrFromInt("); | ||
| 285 | try print(Value.fromInterned(int), writer, level - 1, zcu, opt_sema); | ||
| 286 | try writer.writeAll(")"); | ||
| 287 | } | ||
| 288 | }, | ||
| 289 | .decl => |index| { | ||
| 290 | try writer.writeAll("&"); | ||
| 291 | try zcu.declPtr(index).renderFullyQualifiedName(zcu, writer); | ||
| 292 | }, | ||
| 293 | .comptime_alloc => try writer.writeAll("&(comptime alloc)"), | ||
| 294 | .anon_decl => |anon| switch (ip.indexToKey(anon.val)) { | ||
| 295 | .aggregate => |aggregate| try printAggregate( | ||
| 296 | Value.fromInterned(anon.val), | ||
| 297 | aggregate, | ||
| 298 | writer, | ||
| 299 | level - 1, | ||
| 300 | true, | ||
| 301 | zcu, | ||
| 302 | opt_sema, | ||
| 303 | ), | ||
| 304 | else => { | ||
| 305 | const ty = Type.fromInterned(ip.typeOf(anon.val)); | ||
| 306 | try writer.print("&@as({}, ", .{ty.fmt(zcu)}); | ||
| 307 | try print(Value.fromInterned(anon.val), writer, level - 1, zcu, opt_sema); | ||
| 308 | try writer.writeAll(")"); | ||
| 309 | }, | ||
| 310 | }, | ||
| 311 | .comptime_field => |val| { | ||
| 312 | const ty = Type.fromInterned(ip.typeOf(val)); | ||
| 313 | try writer.print("&@as({}, ", .{ty.fmt(zcu)}); | ||
| 314 | try print(Value.fromInterned(val), writer, level - 1, zcu, opt_sema); | ||
| 315 | try writer.writeAll(")"); | ||
| 316 | }, | ||
| 317 | .eu_payload => |base| { | ||
| 318 | try printPtr(base, writer, true, true, leading_parens, level, zcu, opt_sema); | ||
| 319 | try writer.writeAll(".?"); | ||
| 320 | }, | ||
| 321 | .opt_payload => |base| { | ||
| 322 | try writer.writeAll("("); | ||
| 323 | try printPtr(base, writer, true, true, leading_parens + 1, level, zcu, opt_sema); | ||
| 324 | try writer.writeAll(" catch unreachable"); | ||
| 325 | }, | ||
| 326 | .elem => |elem| { | ||
| 327 | try printPtr(elem.base, writer, true, true, leading_parens, level, zcu, opt_sema); | ||
| 328 | try writer.print("[{d}]", .{elem.index}); | ||
| 329 | }, | ||
| 330 | .field => |field| { | ||
| 331 | try printPtr(field.base, writer, true, true, leading_parens, level, zcu, opt_sema); | ||
| 332 | const base_ty = Type.fromInterned(ip.typeOf(field.base)).childType(zcu); | ||
| 333 | switch (base_ty.zigTypeTag(zcu)) { | ||
| 334 | .Struct => if (base_ty.isTuple(zcu)) { | ||
| 335 | try writer.print("[{d}]", .{field.index}); | ||
| 336 | } else { | ||
| 337 | const field_name = base_ty.structFieldName(@intCast(field.index), zcu).unwrap().?; | ||
| 338 | try writer.print(".{i}", .{field_name.fmt(ip)}); | ||
| 339 | }, | ||
| 340 | .Union => { | ||
| 341 | const tag_ty = base_ty.unionTagTypeHypothetical(zcu); | ||
| 342 | const field_name = tag_ty.enumFieldName(@intCast(field.index), zcu); | ||
| 343 | try writer.print(".{i}", .{field_name.fmt(ip)}); | ||
| 344 | }, | ||
| 345 | .Pointer => switch (field.index) { | ||
| 346 | Value.slice_ptr_index => try writer.writeAll(".ptr"), | ||
| 347 | Value.slice_len_index => try writer.writeAll(".len"), | ||
| 348 | else => unreachable, | ||
| 349 | }, | ||
| 350 | else => unreachable, | ||
| 351 | } | ||
| 352 | }, | ||
| 353 | } | ||
| 354 | } | ||
src/type.zig+5-6| ... | @@ -7,7 +7,6 @@ const Module = @import("Module.zig"); | ... | @@ -7,7 +7,6 @@ const Module = @import("Module.zig"); |
| 7 | const Zcu = Module; | 7 | const Zcu = Module; |
| 8 | const log = std.log.scoped(.Type); | 8 | const log = std.log.scoped(.Type); |
| 9 | const target_util = @import("target.zig"); | 9 | const target_util = @import("target.zig"); |
| 10 | const TypedValue = @import("TypedValue.zig"); | ||
| 11 | const Sema = @import("Sema.zig"); | 10 | const Sema = @import("Sema.zig"); |
| 12 | const InternPool = @import("InternPool.zig"); | 11 | const InternPool = @import("InternPool.zig"); |
| 13 | const Alignment = InternPool.Alignment; | 12 | const Alignment = InternPool.Alignment; |
| ... | @@ -188,8 +187,8 @@ pub const Type = struct { | ... | @@ -188,8 +187,8 @@ pub const Type = struct { |
| 188 | 187 | ||
| 189 | if (info.sentinel != .none) switch (info.flags.size) { | 188 | if (info.sentinel != .none) switch (info.flags.size) { |
| 190 | .One, .C => unreachable, | 189 | .One, .C => unreachable, |
| 191 | .Many => try writer.print("[*:{}]", .{Value.fromInterned(info.sentinel).fmtValue(Type.fromInterned(info.child), mod)}), | 190 | .Many => try writer.print("[*:{}]", .{Value.fromInterned(info.sentinel).fmtValue(mod)}), |
| 192 | .Slice => try writer.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(Type.fromInterned(info.child), mod)}), | 191 | .Slice => try writer.print("[:{}]", .{Value.fromInterned(info.sentinel).fmtValue(mod)}), |
| 193 | } else switch (info.flags.size) { | 192 | } else switch (info.flags.size) { |
| 194 | .One => try writer.writeAll("*"), | 193 | .One => try writer.writeAll("*"), |
| 195 | .Many => try writer.writeAll("[*]"), | 194 | .Many => try writer.writeAll("[*]"), |
| ... | @@ -235,7 +234,7 @@ pub const Type = struct { | ... | @@ -235,7 +234,7 @@ pub const Type = struct { |
| 235 | } else { | 234 | } else { |
| 236 | try writer.print("[{d}:{}]", .{ | 235 | try writer.print("[{d}:{}]", .{ |
| 237 | array_type.len, | 236 | array_type.len, |
| 238 | Value.fromInterned(array_type.sentinel).fmtValue(Type.fromInterned(array_type.child), mod), | 237 | Value.fromInterned(array_type.sentinel).fmtValue(mod), |
| 239 | }); | 238 | }); |
| 240 | try print(Type.fromInterned(array_type.child), writer, mod); | 239 | try print(Type.fromInterned(array_type.child), writer, mod); |
| 241 | } | 240 | } |
| ... | @@ -353,7 +352,7 @@ pub const Type = struct { | ... | @@ -353,7 +352,7 @@ pub const Type = struct { |
| 353 | try print(Type.fromInterned(field_ty), writer, mod); | 352 | try print(Type.fromInterned(field_ty), writer, mod); |
| 354 | 353 | ||
| 355 | if (val != .none) { | 354 | if (val != .none) { |
| 356 | try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(Type.fromInterned(field_ty), mod)}); | 355 | try writer.print(" = {}", .{Value.fromInterned(val).fmtValue(mod)}); |
| 357 | } | 356 | } |
| 358 | } | 357 | } |
| 359 | try writer.writeAll("}"); | 358 | try writer.writeAll("}"); |
| ... | @@ -2481,7 +2480,7 @@ pub const Type = struct { | ... | @@ -2481,7 +2480,7 @@ pub const Type = struct { |
| 2481 | } | 2480 | } |
| 2482 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); | 2481 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); |
| 2483 | if (try field_ty.onePossibleValue(mod)) |field_opv| { | 2482 | if (try field_ty.onePossibleValue(mod)) |field_opv| { |
| 2484 | field_val.* = try field_opv.intern(field_ty, mod); | 2483 | field_val.* = field_opv.toIntern(); |
| 2485 | } else return null; | 2484 | } else return null; |
| 2486 | } | 2485 | } |
| 2487 | 2486 |
test/behavior/basic.zig-25| ... | @@ -693,31 +693,6 @@ test "string concatenation" { | ... | @@ -693,31 +693,6 @@ test "string concatenation" { |
| 693 | try expect(b[len] == 0); | 693 | try expect(b[len] == 0); |
| 694 | } | 694 | } |
| 695 | 695 | ||
| 696 | fn manyptrConcat(comptime s: [*:0]const u8) [*:0]const u8 { | ||
| 697 | return "very " ++ s; | ||
| 698 | } | ||
| 699 | |||
| 700 | test "comptime manyptr concatenation" { | ||
| 701 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 702 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | ||
| 703 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | ||
| 704 | |||
| 705 | const s = "epic"; | ||
| 706 | const actual = manyptrConcat(s); | ||
| 707 | const expected = "very epic"; | ||
| 708 | |||
| 709 | const len = mem.len(actual); | ||
| 710 | const len_with_null = len + 1; | ||
| 711 | { | ||
| 712 | var i: u32 = 0; | ||
| 713 | while (i < len_with_null) : (i += 1) { | ||
| 714 | try expect(actual[i] == expected[i]); | ||
| 715 | } | ||
| 716 | } | ||
| 717 | try expect(actual[len] == 0); | ||
| 718 | try expect(expected[len] == 0); | ||
| 719 | } | ||
| 720 | |||
| 721 | test "result location is optional inside error union" { | 696 | test "result location is optional inside error union" { |
| 722 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 697 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 723 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 698 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
test/cases/compile_errors/compile_log.zig+1-1| ... | @@ -21,7 +21,7 @@ export fn baz() void { | ... | @@ -21,7 +21,7 @@ export fn baz() void { |
| 21 | // | 21 | // |
| 22 | // Compile Log Output: | 22 | // Compile Log Output: |
| 23 | // @as(*const [5:0]u8, "begin") | 23 | // @as(*const [5:0]u8, "begin") |
| 24 | // @as(*const [1:0]u8, "a"), @as(i32, 12), @as(*const [1:0]u8, "b"), @as([]const u8, "hi") | 24 | // @as(*const [1:0]u8, "a"), @as(i32, 12), @as(*const [1:0]u8, "b"), @as([]const u8, "hi"[0..2]) |
| 25 | // @as(*const [3:0]u8, "end") | 25 | // @as(*const [3:0]u8, "end") |
| 26 | // @as(comptime_int, 4) | 26 | // @as(comptime_int, 4) |
| 27 | // @as(*const [5:0]u8, "begin") | 27 | // @as(*const [5:0]u8, "begin") |
test/cases/compile_errors/compile_log_a_pointer_to_an_opaque_value.zig+1-1| ... | @@ -9,4 +9,4 @@ export fn entry() void { | ... | @@ -9,4 +9,4 @@ export fn entry() void { |
| 9 | // :2:5: error: found compile log statement | 9 | // :2:5: error: found compile log statement |
| 10 | // | 10 | // |
| 11 | // Compile Log Output: | 11 | // Compile Log Output: |
| 12 | // @as(*const anyopaque, (function 'entry')) | 12 | // @as(*const anyopaque, &tmp.entry) |
test/cases/compile_errors/reify_type_for_exhaustive_enum_with_undefined_tag_type.zig+1-1| ... | @@ -14,4 +14,4 @@ export fn entry() void { | ... | @@ -14,4 +14,4 @@ export fn entry() void { |
| 14 | // backend=stage2 | 14 | // backend=stage2 |
| 15 | // target=native | 15 | // target=native |
| 16 | // | 16 | // |
| 17 | // :1:13: error: use of undefined value here causes undefined behavior | 17 | // :1:20: error: use of undefined value here causes undefined behavior |
test/cases/compile_errors/reify_type_union_payload_is_undefined.zig+1-1| ... | @@ -9,4 +9,4 @@ comptime { | ... | @@ -9,4 +9,4 @@ comptime { |
| 9 | // backend=stage2 | 9 | // backend=stage2 |
| 10 | // target=native | 10 | // target=native |
| 11 | // | 11 | // |
| 12 | // :1:13: error: use of undefined value here causes undefined behavior | 12 | // :1:20: error: use of undefined value here causes undefined behavior |
test/cases/compile_errors/reify_type_with_undefined.zig+3-3| ... | @@ -28,6 +28,6 @@ comptime { | ... | @@ -28,6 +28,6 @@ comptime { |
| 28 | // backend=stage2 | 28 | // backend=stage2 |
| 29 | // target=native | 29 | // target=native |
| 30 | // | 30 | // |
| 31 | // :2:9: error: use of undefined value here causes undefined behavior | 31 | // :2:16: error: use of undefined value here causes undefined behavior |
| 32 | // :5:9: error: use of undefined value here causes undefined behavior | 32 | // :5:16: error: use of undefined value here causes undefined behavior |
| 33 | // :17:9: error: use of undefined value here causes undefined behavior | 33 | // :17:16: error: use of undefined value here causes undefined behavior |
test/cases/comptime_aggregate_print.zig+2-2| ... | @@ -31,5 +31,5 @@ pub fn main() !void {} | ... | @@ -31,5 +31,5 @@ pub fn main() !void {} |
| 31 | // :20:5: error: found compile log statement | 31 | // :20:5: error: found compile log statement |
| 32 | // | 32 | // |
| 33 | // Compile Log Output: | 33 | // Compile Log Output: |
| 34 | // @as([]i32, .{ (reinterpreted data) }) | 34 | // @as([]i32, &(comptime alloc).buf[0..2]) |
| 35 | // @as([]i32, .{ (reinterpreted data) }) | 35 | // @as([]i32, &(comptime alloc).buf[0..2]) |