Skip to content

Commit

Permalink
Finish implementing the extended name section proposal (#298)
Browse files Browse the repository at this point in the history
* begin implementing extended name section

* add element and data names

* Remove extended name feature

* Print out names in the custom name maps

This commit updates wasmprinter to consult the name section for not only
function/local names but all the other names which are now parsed in the
name section as well.

* Implement the extended name section proposal in `wast`

* Print labels for blocks as well

This recognizes labels in the custom name section when printing wasm
modules and attempts to print the labels. This doesn't yet print the
symbolic name on the `br` or related instructions, but it at least
prints the name on the label instruction itself.

* Fix a test with custom section orderings

* Remove a stray feature

Co-authored-by: Sam Sartor <[email protected]>
  • Loading branch information
alexcrichton and Sam Sartor authored Jul 1, 2021
1 parent 633b624 commit 0486fb4
Show file tree
Hide file tree
Showing 24 changed files with 715 additions and 259 deletions.
82 changes: 52 additions & 30 deletions crates/dump/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,49 @@ impl<'a> Dump<'a> {
Ok(())
}

fn print_name_map(&mut self, thing: &str, n: NameMap<'_>) -> Result<()> {
write!(self.state, "{} names", thing)?;
self.print(n.original_position())?;
let mut map = n.get_map()?;
write!(self.state, "{} count", map.get_count())?;
self.print(map.original_position())?;
for _ in 0..map.get_count() {
write!(self.state, "{:?}", map.read()?)?;
self.print(map.original_position())?;
}
Ok(())
}

fn print_indirect_name_map(
&mut self,
thing_a: &str,
thing_b: &str,
n: IndirectNameMap<'_>,
) -> Result<()> {
write!(self.state, "{} names", thing_b)?;
self.print(n.original_position())?;
let mut outer_map = n.get_indirect_map()?;
write!(self.state, "{} count", outer_map.get_indirect_count())?;
self.print(outer_map.original_position())?;
for _ in 0..outer_map.get_indirect_count() {
let inner = outer_map.read()?;
write!(
self.state,
"{} {} {}s",
thing_a, inner.indirect_index, thing_b,
)?;
self.print(inner.original_position())?;
let mut map = inner.get_map()?;
write!(self.state, "{} count", map.get_count())?;
self.print(map.original_position())?;
for _ in 0..map.get_count() {
write!(self.state, "{:?}", map.read()?)?;
self.print(map.original_position())?;
}
}
Ok(())
}

fn print_custom_name_section(&mut self, name: Name<'_>, end: usize) -> Result<()> {
match name {
Name::Module(n) => {
Expand All @@ -329,36 +372,15 @@ impl<'a> Dump<'a> {
write!(self.state, "{:?}", n.get_name()?)?;
self.print(end)?;
}
Name::Function(n) => {
write!(self.state, "function names")?;
self.print(n.original_position())?;
let mut map = n.get_map()?;
write!(self.state, "{} count", map.get_count())?;
self.print(map.original_position())?;
for _ in 0..map.get_count() {
write!(self.state, "{:?}", map.read()?)?;
self.print(map.original_position())?;
}
}
Name::Local(n) => {
write!(self.state, "local names")?;
self.print(n.original_position())?;
let mut function_map = n.get_function_local_reader()?;
write!(self.state, "{} count", function_map.get_count())?;
self.print(function_map.original_position())?;
for _ in 0..function_map.get_count() {
let function_names = function_map.read()?;
write!(self.state, "function {} locals", function_names.func_index)?;
self.print(function_names.original_position())?;
let mut map = function_names.get_map()?;
write!(self.state, "{} count", map.get_count())?;
self.print(map.original_position())?;
for _ in 0..map.get_count() {
write!(self.state, "{:?}", map.read()?)?;
self.print(map.original_position())?;
}
}
}
Name::Function(n) => self.print_name_map("function", n)?,
Name::Local(n) => self.print_indirect_name_map("function", "local", n)?,
Name::Label(n) => self.print_indirect_name_map("function", "label", n)?,
Name::Type(n) => self.print_name_map("type", n)?,
Name::Table(n) => self.print_name_map("table", n)?,
Name::Memory(n) => self.print_name_map("memory", n)?,
Name::Global(n) => self.print_name_map("global", n)?,
Name::Element(n) => self.print_name_map("element", n)?,
Name::Data(n) => self.print_name_map("data", n)?,
Name::Unknown { ty, range, .. } => {
write!(self.state, "unknown names: {}", ty)?;
self.print(range.start)?;
Expand Down
7 changes: 7 additions & 0 deletions crates/wasmparser/src/binary_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1863,6 +1863,13 @@ impl<'a> BinaryReader<'a> {
0 => Ok(NameType::Module),
1 => Ok(NameType::Function),
2 => Ok(NameType::Local),
3 => Ok(NameType::Label),
4 => Ok(NameType::Type),
5 => Ok(NameType::Table),
6 => Ok(NameType::Memory),
7 => Ok(NameType::Global),
8 => Ok(NameType::Element),
9 => Ok(NameType::Data),
_ => Ok(NameType::Unknown(code)),
}
}
Expand Down
7 changes: 7 additions & 0 deletions crates/wasmparser/src/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,13 @@ pub enum NameType {
Module,
Function,
Local,
Label,
Type,
Table,
Memory,
Global,
Element,
Data,
Unknown(u32),
}

Expand Down
66 changes: 40 additions & 26 deletions crates/wasmparser/src/readers/name_section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ use super::{
};

#[derive(Debug, Copy, Clone)]
pub struct ModuleName<'a> {
pub struct SingleName<'a> {
data: &'a [u8],
offset: usize,
}

impl<'a> ModuleName<'a> {
impl<'a> SingleName<'a> {
pub fn get_name<'b>(&self) -> Result<&'b str>
where
'a: 'b,
Expand Down Expand Up @@ -78,12 +78,12 @@ impl<'a> NamingReader<'a> {
}

#[derive(Debug, Copy, Clone)]
pub struct FunctionName<'a> {
pub struct NameMap<'a> {
data: &'a [u8],
offset: usize,
}

impl<'a> FunctionName<'a> {
impl<'a> NameMap<'a> {
pub fn get_map<'b>(&self) -> Result<NamingReader<'b>>
where
'a: 'b,
Expand All @@ -97,13 +97,13 @@ impl<'a> FunctionName<'a> {
}

#[derive(Debug, Copy, Clone)]
pub struct FunctionLocalName<'a> {
pub func_index: u32,
pub struct IndirectNaming<'a> {
pub indirect_index: u32,
data: &'a [u8],
offset: usize,
}

impl<'a> FunctionLocalName<'a> {
impl<'a> IndirectNaming<'a> {
pub fn get_map<'b>(&self) -> Result<NamingReader<'b>>
where
'a: 'b,
Expand All @@ -116,54 +116,54 @@ impl<'a> FunctionLocalName<'a> {
}
}

pub struct FunctionLocalReader<'a> {
pub struct IndirectNamingReader<'a> {
reader: BinaryReader<'a>,
count: u32,
}

impl<'a> FunctionLocalReader<'a> {
fn new(data: &'a [u8], offset: usize) -> Result<FunctionLocalReader<'a>> {
impl<'a> IndirectNamingReader<'a> {
fn new(data: &'a [u8], offset: usize) -> Result<IndirectNamingReader<'a>> {
let mut reader = BinaryReader::new_with_offset(data, offset);
let count = reader.read_var_u32()?;
Ok(FunctionLocalReader { reader, count })
Ok(IndirectNamingReader { reader, count })
}

pub fn get_count(&self) -> u32 {
pub fn get_indirect_count(&self) -> u32 {
self.count
}

pub fn original_position(&self) -> usize {
self.reader.original_position()
}

pub fn read<'b>(&mut self) -> Result<FunctionLocalName<'b>>
pub fn read<'b>(&mut self) -> Result<IndirectNaming<'b>>
where
'a: 'b,
{
let func_index = self.reader.read_var_u32()?;
let index = self.reader.read_var_u32()?;
let start = self.reader.position;
NamingReader::skip(&mut self.reader)?;
let end = self.reader.position;
Ok(FunctionLocalName {
func_index,
Ok(IndirectNaming {
indirect_index: index,
data: &self.reader.buffer[start..end],
offset: self.reader.original_offset + start,
})
}
}

#[derive(Debug, Copy, Clone)]
pub struct LocalName<'a> {
pub struct IndirectNameMap<'a> {
data: &'a [u8],
offset: usize,
}

impl<'a> LocalName<'a> {
pub fn get_function_local_reader<'b>(&self) -> Result<FunctionLocalReader<'b>>
impl<'a> IndirectNameMap<'a> {
pub fn get_indirect_map<'b>(&self) -> Result<IndirectNamingReader<'b>>
where
'a: 'b,
{
FunctionLocalReader::new(self.data, self.offset)
IndirectNamingReader::new(self.data, self.offset)
}

pub fn original_position(&self) -> usize {
Expand All @@ -173,9 +173,16 @@ impl<'a> LocalName<'a> {

#[derive(Debug, Copy, Clone)]
pub enum Name<'a> {
Module(ModuleName<'a>),
Function(FunctionName<'a>),
Local(LocalName<'a>),
Module(SingleName<'a>),
Function(NameMap<'a>),
Local(IndirectNameMap<'a>),
Label(IndirectNameMap<'a>),
Type(NameMap<'a>),
Table(NameMap<'a>),
Memory(NameMap<'a>),
Global(NameMap<'a>),
Element(NameMap<'a>),
Data(NameMap<'a>),
/// An unknown [name subsection](https://webassembly.github.io/spec/core/appendix/custom.html#subsections).
Unknown {
/// The identifier for this subsection.
Expand Down Expand Up @@ -230,9 +237,16 @@ impl<'a> NameSectionReader<'a> {
let data = &self.reader.buffer[payload_start..payload_end];
self.reader.skip_to(payload_end);
Ok(match ty {
NameType::Module => Name::Module(ModuleName { data, offset }),
NameType::Function => Name::Function(FunctionName { data, offset }),
NameType::Local => Name::Local(LocalName { data, offset }),
NameType::Module => Name::Module(SingleName { data, offset }),
NameType::Function => Name::Function(NameMap { data, offset }),
NameType::Local => Name::Local(IndirectNameMap { data, offset }),
NameType::Label => Name::Label(IndirectNameMap { data, offset }),
NameType::Type => Name::Type(NameMap { data, offset }),
NameType::Table => Name::Table(NameMap { data, offset }),
NameType::Memory => Name::Memory(NameMap { data, offset }),
NameType::Global => Name::Global(NameMap { data, offset }),
NameType::Element => Name::Element(NameMap { data, offset }),
NameType::Data => Name::Data(NameMap { data, offset }),
NameType::Unknown(ty) => Name::Unknown {
ty,
data,
Expand Down
Loading

0 comments on commit 0486fb4

Please sign in to comment.