| ... | ... | @@ -1803,8 +1803,6 @@ pub const Tag = enum(u8) { |
| 1803 | 1803 | ptr_field, |
| 1804 | 1804 | /// A slice. |
| 1805 | 1805 | /// data is extra index of PtrSlice, which contains the ptr and len values |
| 1806 | | /// In order to use this encoding, one must ensure that the `InternPool` |
| 1807 | | /// already contains the slice type corresponding to this payload. |
| 1808 | 1806 | ptr_slice, |
| 1809 | 1807 | /// An optional value that is non-null. |
| 1810 | 1808 | /// data is extra index of `TypeValue`. |
| ... | ... | @@ -2236,7 +2234,11 @@ pub const PtrBaseIndex = struct { |
| 2236 | 2234 | }; |
| 2237 | 2235 | |
| 2238 | 2236 | pub const PtrSlice = struct { |
| 2237 | /// The slice type. |
| 2238 | ty: Index, |
| 2239 | /// A many pointer value. |
| 2239 | 2240 | ptr: Index, |
| 2241 | /// A usize value. |
| 2240 | 2242 | len: Index, |
| 2241 | 2243 | }; |
| 2242 | 2244 | |
| ... | ... | @@ -2606,16 +2608,25 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 2606 | 2608 | .addr = .{ .comptime_field = info.field_val }, |
| 2607 | 2609 | } }; |
| 2608 | 2610 | }, |
| 2609 | | .ptr_int, .ptr_eu_payload, .ptr_opt_payload => { |
| 2611 | .ptr_int => { |
| 2610 | 2612 | const info = ip.extraData(PtrBase, data); |
| 2611 | 2613 | return .{ .ptr = .{ |
| 2612 | 2614 | .ty = info.ty, |
| 2613 | | .addr = switch (item.tag) { |
| 2614 | | .ptr_int => .{ .int = info.base }, |
| 2615 | | .ptr_eu_payload => .{ .eu_payload = info.base }, |
| 2616 | | .ptr_opt_payload => .{ .opt_payload = info.base }, |
| 2617 | | else => unreachable, |
| 2618 | | }, |
| 2615 | .addr = .{ .int = info.base }, |
| 2616 | } }; |
| 2617 | }, |
| 2618 | .ptr_eu_payload => { |
| 2619 | const info = ip.extraData(PtrBase, data); |
| 2620 | return .{ .ptr = .{ |
| 2621 | .ty = info.ty, |
| 2622 | .addr = .{ .eu_payload = info.base }, |
| 2623 | } }; |
| 2624 | }, |
| 2625 | .ptr_opt_payload => { |
| 2626 | const info = ip.extraData(PtrBase, data); |
| 2627 | return .{ .ptr = .{ |
| 2628 | .ty = info.ty, |
| 2629 | .addr = .{ .opt_payload = info.base }, |
| 2619 | 2630 | } }; |
| 2620 | 2631 | }, |
| 2621 | 2632 | .ptr_elem => { |
| ... | ... | @@ -2652,15 +2663,64 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 2652 | 2663 | }, |
| 2653 | 2664 | .ptr_slice => { |
| 2654 | 2665 | const info = ip.extraData(PtrSlice, data); |
| 2655 | | const ptr = ip.indexToKey(info.ptr).ptr; |
| 2656 | | var ptr_type = ip.indexToKey(ptr.ty).ptr_type; |
| 2657 | | assert(ptr_type.size == .Many); |
| 2658 | | ptr_type.size = .Slice; |
| 2659 | | return .{ .ptr = .{ |
| 2660 | | .ty = ip.getAssumeExists(.{ .ptr_type = ptr_type }), |
| 2661 | | .addr = ptr.addr, |
| 2662 | | .len = info.len, |
| 2663 | | } }; |
| 2666 | const ptr_item = ip.items.get(@enumToInt(info.ptr)); |
| 2667 | return .{ |
| 2668 | .ptr = .{ |
| 2669 | .ty = info.ty, |
| 2670 | .addr = switch (ptr_item.tag) { |
| 2671 | .ptr_decl => .{ |
| 2672 | .decl = ip.extraData(PtrDecl, ptr_item.data).decl, |
| 2673 | }, |
| 2674 | .ptr_mut_decl => b: { |
| 2675 | const sub_info = ip.extraData(PtrMutDecl, ptr_item.data); |
| 2676 | break :b .{ .mut_decl = .{ |
| 2677 | .decl = sub_info.decl, |
| 2678 | .runtime_index = sub_info.runtime_index, |
| 2679 | } }; |
| 2680 | }, |
| 2681 | .ptr_comptime_field => .{ |
| 2682 | .comptime_field = ip.extraData(PtrComptimeField, ptr_item.data).field_val, |
| 2683 | }, |
| 2684 | .ptr_int => .{ |
| 2685 | .int = ip.extraData(PtrBase, ptr_item.data).base, |
| 2686 | }, |
| 2687 | .ptr_eu_payload => .{ |
| 2688 | .eu_payload = ip.extraData(PtrBase, ptr_item.data).base, |
| 2689 | }, |
| 2690 | .ptr_opt_payload => .{ |
| 2691 | .opt_payload = ip.extraData(PtrBase, ptr_item.data).base, |
| 2692 | }, |
| 2693 | .ptr_elem => b: { |
| 2694 | // Avoid `indexToKey` recursion by asserting the tag encoding. |
| 2695 | const sub_info = ip.extraData(PtrBaseIndex, ptr_item.data); |
| 2696 | const index_item = ip.items.get(@enumToInt(sub_info.index)); |
| 2697 | break :b switch (index_item.tag) { |
| 2698 | .int_usize => .{ .elem = .{ |
| 2699 | .base = sub_info.base, |
| 2700 | .index = index_item.data, |
| 2701 | } }, |
| 2702 | .int_positive => @panic("TODO"), // implement along with behavior test coverage |
| 2703 | else => unreachable, |
| 2704 | }; |
| 2705 | }, |
| 2706 | .ptr_field => b: { |
| 2707 | // Avoid `indexToKey` recursion by asserting the tag encoding. |
| 2708 | const sub_info = ip.extraData(PtrBaseIndex, ptr_item.data); |
| 2709 | const index_item = ip.items.get(@enumToInt(sub_info.index)); |
| 2710 | break :b switch (index_item.tag) { |
| 2711 | .int_usize => .{ .field = .{ |
| 2712 | .base = sub_info.base, |
| 2713 | .index = index_item.data, |
| 2714 | } }, |
| 2715 | .int_positive => @panic("TODO"), // implement along with behavior test coverage |
| 2716 | else => unreachable, |
| 2717 | }; |
| 2718 | }, |
| 2719 | else => unreachable, |
| 2720 | }, |
| 2721 | .len = info.len, |
| 2722 | }, |
| 2723 | }; |
| 2664 | 2724 | }, |
| 2665 | 2725 | .int_u8 => .{ .int = .{ |
| 2666 | 2726 | .ty = .u8_type, |
| ... | ... | @@ -3340,6 +3400,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3340 | 3400 | } |
| 3341 | 3401 | }, |
| 3342 | 3402 | else => { |
| 3403 | // TODO: change Key.Ptr for slices to reference the manyptr value |
| 3404 | // rather than having an addr field directly. Then we can avoid |
| 3405 | // these problematic calls to pop(), get(), and getOrPutAdapted(). |
| 3343 | 3406 | assert(ptr_type.size == .Slice); |
| 3344 | 3407 | _ = ip.map.pop(); |
| 3345 | 3408 | var new_key = key; |
| ... | ... | @@ -3352,6 +3415,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3352 | 3415 | ip.items.appendAssumeCapacity(.{ |
| 3353 | 3416 | .tag = .ptr_slice, |
| 3354 | 3417 | .data = try ip.addExtra(gpa, PtrSlice{ |
| 3418 | .ty = ptr.ty, |
| 3355 | 3419 | .ptr = ptr_index, |
| 3356 | 3420 | .len = ptr.len, |
| 3357 | 3421 | }), |