Define a "table" concept.

"Table" is to WebAssembly tables as "Heap" is to WebAssembly linear
memories.
This commit is contained in:
Dan Gohman
2018-05-20 07:48:46 -07:00
parent cd75176f10
commit 1b30265c5c
23 changed files with 500 additions and 16 deletions

View File

@@ -172,6 +172,24 @@ impl Heap {
}
}
/// A reference to a table.
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct Table(u32);
entity_impl!(Table, "table");
impl Table {
/// Create a new table reference from its number.
///
/// This method is for use by the parser.
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::MAX {
Some(Table(n))
} else {
None
}
}
}
/// A reference to any of the entities defined in this module.
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub enum AnyEntity {
@@ -195,6 +213,8 @@ pub enum AnyEntity {
SigRef(SigRef),
/// A heap.
Heap(Heap),
/// A table.
Table(Table),
}
impl fmt::Display for AnyEntity {
@@ -210,6 +230,7 @@ impl fmt::Display for AnyEntity {
AnyEntity::FuncRef(r) => r.fmt(f),
AnyEntity::SigRef(r) => r.fmt(f),
AnyEntity::Heap(r) => r.fmt(f),
AnyEntity::Table(r) => r.fmt(f),
}
}
}
@@ -274,6 +295,12 @@ impl From<Heap> for AnyEntity {
}
}
impl From<Table> for AnyEntity {
fn from(r: Table) -> Self {
AnyEntity::Table(r)
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -9,7 +9,7 @@ use ir;
use ir::{DataFlowGraph, ExternalName, Layout, Signature};
use ir::{
Ebb, ExtFuncData, FuncRef, GlobalValue, GlobalValueData, Heap, HeapData, JumpTable,
JumpTableData, SigRef, StackSlot, StackSlotData,
JumpTableData, SigRef, StackSlot, StackSlotData, Table, TableData,
};
use ir::{EbbOffsets, InstEncodings, JumpTables, SourceLocs, StackSlots, ValueLocations};
use isa::{EncInfo, Encoding, Legalize, TargetIsa};
@@ -42,6 +42,9 @@ pub struct Function {
/// Heaps referenced.
pub heaps: PrimaryMap<ir::Heap, ir::HeapData>,
/// Tables referenced.
pub tables: PrimaryMap<ir::Table, ir::TableData>,
/// Jump tables used in this function.
pub jump_tables: JumpTables,
@@ -82,6 +85,7 @@ impl Function {
stack_limit: None,
global_values: PrimaryMap::new(),
heaps: PrimaryMap::new(),
tables: PrimaryMap::new(),
jump_tables: PrimaryMap::new(),
dfg: DataFlowGraph::new(),
layout: Layout::new(),
@@ -98,6 +102,7 @@ impl Function {
self.stack_slots.clear();
self.global_values.clear();
self.heaps.clear();
self.tables.clear();
self.jump_tables.clear();
self.dfg.clear();
self.layout.clear();
@@ -157,6 +162,11 @@ impl Function {
self.heaps.push(data)
}
/// Declares a table accessible to the function.
pub fn create_table(&mut self, data: TableData) -> Table {
self.tables.push(data)
}
/// Return an object that can display this function with correct ISA-specific annotations.
pub fn display<'a, I: Into<Option<&'a TargetIsa>>>(&'a self, isa: I) -> DisplayFunction<'a> {
DisplayFunction(self, isa.into())

View File

@@ -18,6 +18,7 @@ mod memflags;
mod progpoint;
mod sourceloc;
pub mod stackslot;
mod table;
mod trapcode;
pub mod types;
mod valueloc;
@@ -25,7 +26,7 @@ mod valueloc;
pub use ir::builder::{InsertBuilder, InstBuilder, InstBuilderBase, InstInserterBase};
pub use ir::dfg::{DataFlowGraph, ValueDef};
pub use ir::entities::{
Ebb, FuncRef, GlobalValue, Heap, Inst, JumpTable, SigRef, StackSlot, Value,
Ebb, FuncRef, GlobalValue, Heap, Inst, JumpTable, SigRef, StackSlot, Table, Value,
};
pub use ir::extfunc::{AbiParam, ArgumentExtension, ArgumentPurpose, ExtFuncData, Signature};
pub use ir::extname::ExternalName;
@@ -40,6 +41,7 @@ pub use ir::memflags::MemFlags;
pub use ir::progpoint::{ExpandedProgramPoint, ProgramOrder, ProgramPoint};
pub use ir::sourceloc::SourceLoc;
pub use ir::stackslot::{StackSlotData, StackSlotKind, StackSlots};
pub use ir::table::TableData;
pub use ir::trapcode::TrapCode;
pub use ir::types::Type;
pub use ir::valueloc::{ArgumentLoc, ValueLoc};

View File

@@ -0,0 +1,32 @@
//! Tables.
use ir::immediates::Imm64;
use ir::GlobalValue;
use std::fmt;
/// Information about a table declaration.
#[derive(Clone)]
pub struct TableData {
/// Global value giving the address of the start of the table.
pub base_gv: GlobalValue,
/// Guaranteed minimum table size in elements. Table accesses before `min_size` don't need
/// bounds checking.
pub min_size: Imm64,
/// Global value giving the current bound of the table, in elements.
pub bound_gv: GlobalValue,
/// The size of a table element, in bytes.
pub element_size: Imm64,
}
impl fmt::Display for TableData {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}, min {}, bound {}, element_size {}",
self.base_gv, self.min_size, self.bound_gv, self.element_size
)
}
}

View File

@@ -16,10 +16,13 @@ pub enum TrapCode {
/// A `heap_addr` instruction detected an out-of-bounds error.
///
/// Some out-of-bounds heap accesses are detected by a segmentation fault on the heap guard
/// pages.
/// Note that not all out-of-bounds heap accesses are reported this way;
/// some are detected by a segmentation fault on the heap guard pages.
HeapOutOfBounds,
/// A `table_addr` instruction detected an out-of-bounds error.
TableOutOfBounds,
/// Other bounds checking error.
OutOfBounds,
@@ -52,6 +55,7 @@ impl Display for TrapCode {
let identifier = match *self {
StackOverflow => "stk_ovf",
HeapOutOfBounds => "heap_oob",
TableOutOfBounds => "table_oob",
OutOfBounds => "oob",
IndirectCallToNull => "icall_null",
BadSignature => "bad_sig",
@@ -73,6 +77,7 @@ impl FromStr for TrapCode {
match s {
"stk_ovf" => Ok(StackOverflow),
"heap_oob" => Ok(HeapOutOfBounds),
"table_oob" => Ok(TableOutOfBounds),
"oob" => Ok(OutOfBounds),
"icall_null" => Ok(IndirectCallToNull),
"bad_sig" => Ok(BadSignature),
@@ -92,9 +97,10 @@ mod tests {
use std::string::ToString;
// Everything but user-defined codes.
const CODES: [TrapCode; 8] = [
const CODES: [TrapCode; 9] = [
TrapCode::StackOverflow,
TrapCode::HeapOutOfBounds,
TrapCode::TableOutOfBounds,
TrapCode::OutOfBounds,
TrapCode::IndirectCallToNull,
TrapCode::BadSignature,