(&self, sf: Lrc<SourceFile>)
| 709 | } |
| 710 | |
| 711 | fn def_debug_file(&self, sf: Lrc<SourceFile>) -> DebugFileSpirv<'tcx> { |
| 712 | *self |
| 713 | .debug_file_cache |
| 714 | .borrow_mut() |
| 715 | .entry(DebugFileKey(sf)) |
| 716 | .or_insert_with_key(|DebugFileKey(sf)| { |
| 717 | let mut builder = self.builder(Default::default()); |
| 718 | |
| 719 | // FIXME(eddyb) it would be nicer if we could just rely on |
| 720 | // `RealFileName::to_string_lossy` returning `Cow<'_, str>`, |
| 721 | // but sadly that `'_` is the lifetime of the temporary `Lrc`, |
| 722 | // not `'tcx`, so we have to arena-allocate to get `&'tcx str`. |
| 723 | let file_name = match &sf.name { |
| 724 | FileName::Real(name) => { |
| 725 | name.to_string_lossy(FileNameDisplayPreference::Remapped) |
| 726 | } |
| 727 | _ => sf.name.prefer_remapped().to_string().into(), |
| 728 | }; |
| 729 | let file_name = { |
| 730 | // FIXME(eddyb) it should be possible to arena-allocate a |
| 731 | // `&str` directly, but it would require upstream changes, |
| 732 | // and strings are handled by string interning in `rustc`. |
| 733 | fn arena_alloc_slice<'tcx, T: Copy>( |
| 734 | dropless_arena: &'tcx DroplessArena, |
| 735 | xs: &[T], |
| 736 | ) -> &'tcx [T] { |
| 737 | if xs.is_empty() { |
| 738 | &[] |
| 739 | } else { |
| 740 | dropless_arena.alloc_slice(xs) |
| 741 | } |
| 742 | } |
| 743 | str::from_utf8(arena_alloc_slice(self.dropless_arena, file_name.as_bytes())) |
| 744 | .unwrap() |
| 745 | }; |
| 746 | let file_name_op_string_id = builder.string(file_name.to_owned()); |
| 747 | |
| 748 | let file_contents = self |
| 749 | .source_map |
| 750 | .span_to_snippet(Span::with_root_ctxt(sf.start_pos, sf.end_pos)) |
| 751 | .ok(); |
| 752 | |
| 753 | // HACK(eddyb) this logic is duplicated from `spirt::spv::lift`. |
| 754 | let op_source_and_continued_chunks = file_contents.as_ref().map(|contents| { |
| 755 | // The maximum word count is `2**16 - 1`, the first word is |
| 756 | // taken up by the opcode & word count, and one extra byte is |
| 757 | // taken up by the nil byte at the end of the LiteralString. |
| 758 | const MAX_OP_SOURCE_CONT_CONTENTS_LEN: usize = (0xffff - 1) * 4 - 1; |
| 759 | |
| 760 | // `OpSource` has 3 more operands than `OpSourceContinued`, |
| 761 | // and each of them take up exactly one word. |
| 762 | const MAX_OP_SOURCE_CONTENTS_LEN: usize = |
| 763 | MAX_OP_SOURCE_CONT_CONTENTS_LEN - 3 * 4; |
| 764 | |
| 765 | let (op_source_str, mut all_op_source_continued_str) = |
| 766 | contents.split_at(contents.len().min(MAX_OP_SOURCE_CONTENTS_LEN)); |
| 767 | |
| 768 | // FIXME(eddyb) `spirt::spv::lift` should use this. |
no test coverage detected