allow module environment to parse name section

This commit is contained in:
data-pup
2019-06-28 19:29:53 +00:00
committed by Benjamin Bouvier
parent 3293ca6b69
commit ac2ca6116b
5 changed files with 119 additions and 16 deletions

View File

@@ -17,7 +17,7 @@ use cranelift_codegen::ir::immediates::{Offset32, Uimm64};
use cranelift_codegen::ir::types::*;
use cranelift_codegen::ir::{self, InstBuilder};
use cranelift_codegen::isa::TargetFrontendConfig;
use cranelift_entity::{EntityRef, PrimaryMap};
use cranelift_entity::{EntityRef, PrimaryMap, SecondaryMap};
use std::boxed::Box;
use std::string::String;
use std::vec::Vec;
@@ -124,6 +124,9 @@ pub struct DummyEnvironment {
/// Instructs to collect debug data during translation.
debug_info: bool,
/// Function names.
function_names: SecondaryMap<FuncIndex, String>,
}
impl DummyEnvironment {
@@ -135,6 +138,7 @@ impl DummyEnvironment {
func_bytecode_sizes: Vec::new(),
return_mode,
debug_info,
function_names: SecondaryMap::new(),
}
}
@@ -152,6 +156,12 @@ impl DummyEnvironment {
pub fn get_num_func_imports(&self) -> usize {
self.info.imported_funcs.len()
}
/// Return the name of the function, if a name for the function with
/// the corresponding index exists.
pub fn get_func_name(&self, func_index: FuncIndex) -> Option<&str> {
self.function_names.get(func_index).map(String::as_ref)
}
}
/// The `FuncEnvironment` implementation for use by the `DummyEnvironment`.
@@ -539,4 +549,9 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
self.info.function_bodies.push(func);
Ok(())
}
fn declare_func_name(&mut self, func_index: FuncIndex, name: &'data str) -> WasmResult<()> {
self.function_names[func_index] = String::from(name);
Ok(())
}
}

View File

@@ -468,6 +468,14 @@ pub trait ModuleEnvironment<'data> {
data: &'data [u8],
) -> WasmResult<()>;
/// Declares the name of a function to the environment.
///
/// By default this does nothing, but implementations can use this to read
/// the function name subsection of the custom name section if desired.
fn declare_func_name(&mut self, _func_index: FuncIndex, _name: &'data str) -> WasmResult<()> {
Ok(())
}
/// Indicates that a custom section has been found in the wasm file
fn custom_section(&mut self, name: &'data str, data: &'data [u8]) -> WasmResult<()> {
drop((name, data));

View File

@@ -4,10 +4,10 @@ use crate::environ::{ModuleEnvironment, WasmError, WasmResult};
use crate::sections_translator::{
parse_code_section, parse_data_section, parse_element_section, parse_export_section,
parse_function_section, parse_global_section, parse_import_section, parse_memory_section,
parse_start_section, parse_table_section, parse_type_section,
parse_name_section, parse_start_section, parse_table_section, parse_type_section,
};
use cranelift_codegen::timing;
use wasmparser::{ModuleReader, SectionCode};
use wasmparser::{CustomSectionKind, ModuleReader, SectionCode};
/// Translate a sequence of bytes forming a valid Wasm binary into a list of valid Cranelift IR
/// [`Function`](cranelift_codegen::ir::Function).
@@ -83,6 +83,14 @@ pub fn translate_module<'data>(
});
}
SectionCode::Custom {
kind: CustomSectionKind::Name,
name: _,
} => {
let names = section.get_name_section_reader()?;
parse_name_section(names, environ)?;
}
SectionCode::Custom { name, kind: _ } => {
let mut reader = section.get_binary_reader();
let len = reader.bytes_remaining();

View File

@@ -12,7 +12,7 @@ use crate::translation_utils::{
tabletype_to_type, type_to_type, FuncIndex, Global, GlobalIndex, GlobalInit, Memory,
MemoryIndex, SignatureIndex, Table, TableElementType, TableIndex,
};
use crate::wasm_unsupported;
use crate::{wasm_unsupported, HashMap};
use core::convert::TryFrom;
use cranelift_codegen::ir::{self, AbiParam, Signature};
use cranelift_entity::EntityRef;
@@ -21,8 +21,8 @@ use wasmparser::{
self, CodeSectionReader, Data, DataKind, DataSectionReader, Element, ElementKind,
ElementSectionReader, Export, ExportSectionReader, ExternalKind, FuncType,
FunctionSectionReader, GlobalSectionReader, GlobalType, ImportSectionEntryType,
ImportSectionReader, MemorySectionReader, MemoryType, Operator, TableSectionReader,
TypeSectionReader,
ImportSectionReader, MemorySectionReader, MemoryType, NameSectionReader, Naming, NamingReader,
Operator, TableSectionReader, TypeSectionReader,
};
/// Parses the Type section of the wasm module.
@@ -351,3 +351,47 @@ pub fn parse_data_section<'data>(
Ok(())
}
/// Parses the Name section of the wasm module.
pub fn parse_name_section<'data>(
mut names: NameSectionReader<'data>,
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
while let Ok(subsection) = names.read() {
match subsection {
wasmparser::Name::Function(function_subsection) => {
if let Some(function_names) = function_subsection
.get_map()
.ok()
.and_then(parse_function_name_subsection)
{
for (index, name) in function_names {
environ.declare_func_name(index, name)?;
}
}
return Ok(());
}
wasmparser::Name::Local(_) | wasmparser::Name::Module(_) => {}
};
}
Ok(())
}
fn parse_function_name_subsection<'data>(
mut naming_reader: NamingReader<'data>,
) -> Option<HashMap<FuncIndex, &str>> {
let mut function_names = HashMap::new();
for _ in 0..naming_reader.get_count() {
let Naming { index, name } = naming_reader.read().ok()?;
if function_names
.insert(FuncIndex::from_u32(index), name)
.is_some()
{
// If the function index has been previously seen, then we
// break out of the loop and early return `None`, because these
// should be unique.
return None;
}
}
return Some(function_names);
}