| ... | @@ -1803,8 +1803,6 @@ pub const Tag = enum(u8) { | ... | @@ -1803,8 +1803,6 @@ pub const Tag = enum(u8) { |
| 1803 | ptr_field, | 1803 | ptr_field, |
| 1804 | /// A slice. | 1804 | /// A slice. |
| 1805 | /// data is extra index of PtrSlice, which contains the ptr and len values | 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 | ptr_slice, | 1806 | ptr_slice, |
| 1809 | /// An optional value that is non-null. | 1807 | /// An optional value that is non-null. |
| 1810 | /// data is extra index of `TypeValue`. | 1808 | /// data is extra index of `TypeValue`. |
| ... | @@ -2236,7 +2234,11 @@ pub const PtrBaseIndex = struct { | ... | @@ -2236,7 +2234,11 @@ pub const PtrBaseIndex = struct { |
| 2236 | }; | 2234 | }; |
| 2237 | | 2235 | |
| 2238 | pub const PtrSlice = struct { | 2236 | pub const PtrSlice = struct { |
| | 2237 | /// The slice type. |
| | 2238 | ty: Index, |
| | 2239 | /// A many pointer value. |
| 2239 | ptr: Index, | 2240 | ptr: Index, |
| | 2241 | /// A usize value. |
| 2240 | len: Index, | 2242 | len: Index, |
| 2241 | }; | 2243 | }; |
| 2242 | | 2244 | |
| ... | @@ -2606,16 +2608,25 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { | ... | @@ -2606,16 +2608,25 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 2606 | .addr = .{ .comptime_field = info.field_val }, | 2608 | .addr = .{ .comptime_field = info.field_val }, |
| 2607 | } }; | 2609 | } }; |
| 2608 | }, | 2610 | }, |
| 2609 | .ptr_int, .ptr_eu_payload, .ptr_opt_payload => { | 2611 | .ptr_int => { |
| 2610 | const info = ip.extraData(PtrBase, data); | 2612 | const info = ip.extraData(PtrBase, data); |
| 2611 | return .{ .ptr = .{ | 2613 | return .{ .ptr = .{ |
| 2612 | .ty = info.ty, | 2614 | .ty = info.ty, |
| 2613 | .addr = switch (item.tag) { | 2615 | .addr = .{ .int = info.base }, |
| 2614 | .ptr_int => .{ .int = info.base }, | 2616 | } }; |
| 2615 | .ptr_eu_payload => .{ .eu_payload = info.base }, | 2617 | }, |
| 2616 | .ptr_opt_payload => .{ .opt_payload = info.base }, | 2618 | .ptr_eu_payload => { |
| 2617 | else => unreachable, | 2619 | const info = ip.extraData(PtrBase, data); |
| 2618 | }, | 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 | .ptr_elem => { | 2632 | .ptr_elem => { |
| ... | @@ -2652,15 +2663,64 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { | ... | @@ -2652,15 +2663,64 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 2652 | }, | 2663 | }, |
| 2653 | .ptr_slice => { | 2664 | .ptr_slice => { |
| 2654 | const info = ip.extraData(PtrSlice, data); | 2665 | const info = ip.extraData(PtrSlice, data); |
| 2655 | const ptr = ip.indexToKey(info.ptr).ptr; | 2666 | const ptr_item = ip.items.get(@enumToInt(info.ptr)); |
| 2656 | var ptr_type = ip.indexToKey(ptr.ty).ptr_type; | 2667 | return .{ |
| 2657 | assert(ptr_type.size == .Many); | 2668 | .ptr = .{ |
| 2658 | ptr_type.size = .Slice; | 2669 | .ty = info.ty, |
| 2659 | return .{ .ptr = .{ | 2670 | .addr = switch (ptr_item.tag) { |
| 2660 | .ty = ip.getAssumeExists(.{ .ptr_type = ptr_type }), | 2671 | .ptr_decl => .{ |
| 2661 | .addr = ptr.addr, | 2672 | .decl = ip.extraData(PtrDecl, ptr_item.data).decl, |
| 2662 | .len = info.len, | 2673 | }, |
| 2663 | } }; | 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 | .int_u8 => .{ .int = .{ | 2725 | .int_u8 => .{ .int = .{ |
| 2666 | .ty = .u8_type, | 2726 | .ty = .u8_type, |
| ... | @@ -3340,6 +3400,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -3340,6 +3400,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3340 | } | 3400 | } |
| 3341 | }, | 3401 | }, |
| 3342 | else => { | 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 | assert(ptr_type.size == .Slice); | 3406 | assert(ptr_type.size == .Slice); |
| 3344 | _ = ip.map.pop(); | 3407 | _ = ip.map.pop(); |
| 3345 | var new_key = key; | 3408 | var new_key = key; |
| ... | @@ -3352,6 +3415,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -3352,6 +3415,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 3352 | ip.items.appendAssumeCapacity(.{ | 3415 | ip.items.appendAssumeCapacity(.{ |
| 3353 | .tag = .ptr_slice, | 3416 | .tag = .ptr_slice, |
| 3354 | .data = try ip.addExtra(gpa, PtrSlice{ | 3417 | .data = try ip.addExtra(gpa, PtrSlice{ |
| | 3418 | .ty = ptr.ty, |
| 3355 | .ptr = ptr_index, | 3419 | .ptr = ptr_index, |
| 3356 | .len = ptr.len, | 3420 | .len = ptr.len, |
| 3357 | }), | 3421 | }), |