Skip to content

Commit

Permalink
Add a convenience for getting the function tables
Browse files Browse the repository at this point in the history
If applicable modules typically have one function table when coming from
languages like C or Rust, so add a convenience function that returns the
function table if it's present.
  • Loading branch information
alexcrichton committed Feb 19, 2019
1 parent 0d6a098 commit feb7f05
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/module/functions/local_function/emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl Emit<'_, '_> {
let old = self.id;
self.id = id;

match &self.func.get(id) {
match self.func.get(id) {
Const(e) => e.value.emit(self.encoder),
Block(e) => self.visit_block(e),
BrTable(e) => self.visit_br_table(e),
Expand Down
1 change: 1 addition & 0 deletions src/module/functions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ impl Emit for ModuleFunctions {
let bytes = functions
.into_par_iter()
.map(|(id, func, _size)| {
log::debug!("emit function {:?} {:?}", id, cx.module.funcs.get(id).name);
let mut wasm = Vec::new();
let mut encoder = Encoder::new(&mut wasm);
let local_indices = func.emit_locals(id, cx.module, cx.used, &mut encoder);
Expand Down
25 changes: 25 additions & 0 deletions src/module/tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,31 @@ impl ModuleTables {
pub fn iter(&self) -> impl Iterator<Item = &Table> {
self.arena.iter().map(|p| p.1)
}

/// Finds a unique function table in a module.
///
/// Modules produced by compilers like LLVM typically have one function
/// table for indirect function calls. This function will look for a single
/// function table inside this module, and return that if found. If no
/// function tables are present `None` will be returned
///
/// # Errors
///
/// Returns an error if there are two function tables in this module
pub fn main_function_table(&self) -> Result<Option<TableId>> {
let mut tables = self.iter().filter_map(|t| match t.kind {
TableKind::Function(_) => Some(t.id()),
_ => None,
});
let id = match tables.next() {
Some(id) => id,
None => return Ok(None),
};
if tables.next().is_some() {
failure::bail!("module contains more than one function table");
}
Ok(Some(id))
}
}

impl Module {
Expand Down

0 comments on commit feb7f05

Please sign in to comment.