Combine VisibleTranslationState and TranslationState (#1076)

`VisibleTranslationState` was a wrapper around a `TranslationState` that was
meant to public API consumers outside of this crate. However, the internal
`TranslationState` and all its methods were still publicly exposed! This commit
simplifies and remedies the situation by combining them into a single
`TranslationState` type. Most of its methods are only `pub(crate)` now, not
visible to the entire world. The only methods that are `pub` are the ones that
`VisibleTranslationState` exposed.
This commit is contained in:
Nick Fitzgerald
2019-09-25 12:07:54 -07:00
committed by Sean Stangl
parent 46ab1b4103
commit 8c3072c774
4 changed files with 42 additions and 50 deletions

View File

@@ -6,7 +6,7 @@
//! //!
//! [Wasmtime]: https://github.com/CraneStation/wasmtime //! [Wasmtime]: https://github.com/CraneStation/wasmtime
use crate::state::VisibleTranslationState; use crate::state::TranslationState;
use crate::translation_utils::{ use crate::translation_utils::{
FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, SignatureIndex, Table, TableIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, SignatureIndex, Table, TableIndex,
}; };
@@ -281,7 +281,7 @@ pub trait FuncEnvironment {
&mut self, &mut self,
_op: &Operator, _op: &Operator,
_builder: &mut FunctionBuilder, _builder: &mut FunctionBuilder,
_state: &VisibleTranslationState, _state: &TranslationState,
) -> WasmResult<()> { ) -> WasmResult<()> {
Ok(()) Ok(())
} }
@@ -292,7 +292,7 @@ pub trait FuncEnvironment {
&mut self, &mut self,
_op: &Operator, _op: &Operator,
_builder: &mut FunctionBuilder, _builder: &mut FunctionBuilder,
_state: &VisibleTranslationState, _state: &TranslationState,
) -> WasmResult<()> { ) -> WasmResult<()> {
Ok(()) Ok(())
} }

View File

@@ -6,7 +6,7 @@
use crate::code_translator::translate_operator; use crate::code_translator::translate_operator;
use crate::environ::{FuncEnvironment, ReturnMode, WasmResult}; use crate::environ::{FuncEnvironment, ReturnMode, WasmResult};
use crate::state::{TranslationState, VisibleTranslationState}; use crate::state::TranslationState;
use crate::translation_utils::get_vmctx_value_label; use crate::translation_utils::get_vmctx_value_label;
use crate::wasm_unsupported; use crate::wasm_unsupported;
use cranelift_codegen::entity::EntityRef; use cranelift_codegen::entity::EntityRef;
@@ -215,9 +215,9 @@ fn parse_function_body<FE: FuncEnvironment + ?Sized>(
while !state.control_stack.is_empty() { while !state.control_stack.is_empty() {
builder.set_srcloc(cur_srcloc(&reader)); builder.set_srcloc(cur_srcloc(&reader));
let op = reader.read_operator()?; let op = reader.read_operator()?;
environ.before_translate_operator(&op, builder, &VisibleTranslationState::new(state))?; environ.before_translate_operator(&op, builder, state)?;
translate_operator(&op, builder, state, environ)?; translate_operator(&op, builder, state, environ)?;
environ.after_translate_operator(&op, builder, &VisibleTranslationState::new(state))?; environ.after_translate_operator(&op, builder, state)?;
} }
// The final `End` operator left us in the exit block where we need to manually add a return // The final `End` operator left us in the exit block where we need to manually add a return

View File

@@ -62,7 +62,7 @@ pub use crate::environ::{
}; };
pub use crate::func_translator::FuncTranslator; pub use crate::func_translator::FuncTranslator;
pub use crate::module_translator::translate_module; pub use crate::module_translator::translate_module;
pub use crate::state::VisibleTranslationState; pub use crate::state::TranslationState;
pub use crate::translation_utils::{ pub use crate::translation_utils::{
get_vmctx_value_label, DefinedFuncIndex, DefinedGlobalIndex, DefinedMemoryIndex, get_vmctx_value_label, DefinedFuncIndex, DefinedGlobalIndex, DefinedMemoryIndex,
DefinedTableIndex, FuncIndex, Global, GlobalIndex, GlobalInit, Memory, MemoryIndex, DefinedTableIndex, FuncIndex, Global, GlobalIndex, GlobalInit, Memory, MemoryIndex,

View File

@@ -124,28 +124,6 @@ impl ControlStackFrame {
} }
} }
/// VisibleTranslationState wraps a TranslationState with an interface appropriate for users
/// outside this `cranelift-wasm`.
///
/// VisibleTranslationState is currently very minimal (only exposing reachability information), but
/// is anticipated to grow in the future, with functions to inspect or modify the wasm operand
/// stack for example.
pub struct VisibleTranslationState<'a> {
state: &'a TranslationState,
}
impl<'a> VisibleTranslationState<'a> {
/// Build a VisibleTranslationState from an existing TranslationState
pub fn new(state: &'a TranslationState) -> Self {
VisibleTranslationState { state }
}
/// True if the current translation state expresses reachable code, false if it is unreachable
pub fn reachable(&self) -> bool {
self.state.reachable
}
}
/// Contains information passed along during the translation and that records: /// Contains information passed along during the translation and that records:
/// ///
/// - The current value and control stacks. /// - The current value and control stacks.
@@ -154,12 +132,12 @@ impl<'a> VisibleTranslationState<'a> {
pub struct TranslationState { pub struct TranslationState {
/// A stack of values corresponding to the active values in the input wasm function at this /// A stack of values corresponding to the active values in the input wasm function at this
/// point. /// point.
pub stack: Vec<Value>, pub(crate) stack: Vec<Value>,
/// A stack of active control flow operations at this point in the input wasm function. /// A stack of active control flow operations at this point in the input wasm function.
pub control_stack: Vec<ControlStackFrame>, pub(crate) control_stack: Vec<ControlStackFrame>,
/// Is the current translation state still reachable? This is false when translating operators /// Is the current translation state still reachable? This is false when translating operators
/// like End, Return, or Unreachable. /// like End, Return, or Unreachable.
pub reachable: bool, pub(crate) reachable: bool,
// Map of global variables that have already been created by `FuncEnvironment::make_global`. // Map of global variables that have already been created by `FuncEnvironment::make_global`.
globals: HashMap<GlobalIndex, GlobalVariable>, globals: HashMap<GlobalIndex, GlobalVariable>,
@@ -181,9 +159,18 @@ pub struct TranslationState {
functions: HashMap<FuncIndex, (ir::FuncRef, usize)>, functions: HashMap<FuncIndex, (ir::FuncRef, usize)>,
} }
// Public methods that are exposed to non-`cranelift_wasm` API consumers.
impl TranslationState {
/// True if the current translation state expresses reachable code, false if it is unreachable.
#[inline]
pub fn reachable(&self) -> bool {
self.reachable
}
}
impl TranslationState { impl TranslationState {
/// Construct a new, empty, `TranslationState` /// Construct a new, empty, `TranslationState`
pub fn new() -> Self { pub(crate) fn new() -> Self {
Self { Self {
stack: Vec::new(), stack: Vec::new(),
control_stack: Vec::new(), control_stack: Vec::new(),
@@ -211,7 +198,7 @@ impl TranslationState {
/// ///
/// This resets the state to containing only a single block representing the whole function. /// This resets the state to containing only a single block representing the whole function.
/// The exit block is the last block in the function which will contain the return instruction. /// The exit block is the last block in the function which will contain the return instruction.
pub fn initialize(&mut self, sig: &ir::Signature, exit_block: Ebb) { pub(crate) fn initialize(&mut self, sig: &ir::Signature, exit_block: Ebb) {
self.clear(); self.clear();
self.push_block( self.push_block(
exit_block, exit_block,
@@ -223,34 +210,34 @@ impl TranslationState {
} }
/// Push a value. /// Push a value.
pub fn push1(&mut self, val: Value) { pub(crate) fn push1(&mut self, val: Value) {
self.stack.push(val); self.stack.push(val);
} }
/// Push multiple values. /// Push multiple values.
pub fn pushn(&mut self, vals: &[Value]) { pub(crate) fn pushn(&mut self, vals: &[Value]) {
self.stack.extend_from_slice(vals); self.stack.extend_from_slice(vals);
} }
/// Pop one value. /// Pop one value.
pub fn pop1(&mut self) -> Value { pub(crate) fn pop1(&mut self) -> Value {
self.stack.pop().unwrap() self.stack.pop().unwrap()
} }
/// Peek at the top of the stack without popping it. /// Peek at the top of the stack without popping it.
pub fn peek1(&self) -> Value { pub(crate) fn peek1(&self) -> Value {
*self.stack.last().unwrap() *self.stack.last().unwrap()
} }
/// Pop two values. Return them in the order they were pushed. /// Pop two values. Return them in the order they were pushed.
pub fn pop2(&mut self) -> (Value, Value) { pub(crate) fn pop2(&mut self) -> (Value, Value) {
let v2 = self.stack.pop().unwrap(); let v2 = self.stack.pop().unwrap();
let v1 = self.stack.pop().unwrap(); let v1 = self.stack.pop().unwrap();
(v1, v2) (v1, v2)
} }
/// Pop three values. Return them in the order they were pushed. /// Pop three values. Return them in the order they were pushed.
pub fn pop3(&mut self) -> (Value, Value, Value) { pub(crate) fn pop3(&mut self) -> (Value, Value, Value) {
let v3 = self.stack.pop().unwrap(); let v3 = self.stack.pop().unwrap();
let v2 = self.stack.pop().unwrap(); let v2 = self.stack.pop().unwrap();
let v1 = self.stack.pop().unwrap(); let v1 = self.stack.pop().unwrap();
@@ -260,18 +247,18 @@ impl TranslationState {
/// Pop the top `n` values on the stack. /// Pop the top `n` values on the stack.
/// ///
/// The popped values are not returned. Use `peekn` to look at them before popping. /// The popped values are not returned. Use `peekn` to look at them before popping.
pub fn popn(&mut self, n: usize) { pub(crate) fn popn(&mut self, n: usize) {
let new_len = self.stack.len() - n; let new_len = self.stack.len() - n;
self.stack.truncate(new_len); self.stack.truncate(new_len);
} }
/// Peek at the top `n` values on the stack in the order they were pushed. /// Peek at the top `n` values on the stack in the order they were pushed.
pub fn peekn(&self, n: usize) -> &[Value] { pub(crate) fn peekn(&self, n: usize) -> &[Value] {
&self.stack[self.stack.len() - n..] &self.stack[self.stack.len() - n..]
} }
/// Push a block on the control stack. /// Push a block on the control stack.
pub fn push_block(&mut self, following_code: Ebb, num_result_types: usize) { pub(crate) fn push_block(&mut self, following_code: Ebb, num_result_types: usize) {
self.control_stack.push(ControlStackFrame::Block { self.control_stack.push(ControlStackFrame::Block {
destination: following_code, destination: following_code,
original_stack_size: self.stack.len(), original_stack_size: self.stack.len(),
@@ -281,7 +268,7 @@ impl TranslationState {
} }
/// Push a loop on the control stack. /// Push a loop on the control stack.
pub fn push_loop(&mut self, header: Ebb, following_code: Ebb, num_result_types: usize) { pub(crate) fn push_loop(&mut self, header: Ebb, following_code: Ebb, num_result_types: usize) {
self.control_stack.push(ControlStackFrame::Loop { self.control_stack.push(ControlStackFrame::Loop {
header, header,
destination: following_code, destination: following_code,
@@ -291,7 +278,12 @@ impl TranslationState {
} }
/// Push an if on the control stack. /// Push an if on the control stack.
pub fn push_if(&mut self, branch_inst: Inst, following_code: Ebb, num_result_types: usize) { pub(crate) fn push_if(
&mut self,
branch_inst: Inst,
following_code: Ebb,
num_result_types: usize,
) {
self.control_stack.push(ControlStackFrame::If { self.control_stack.push(ControlStackFrame::If {
branch_inst, branch_inst,
destination: following_code, destination: following_code,
@@ -308,7 +300,7 @@ impl TranslationState {
/// Get the `GlobalVariable` reference that should be used to access the global variable /// Get the `GlobalVariable` reference that should be used to access the global variable
/// `index`. Create the reference if necessary. /// `index`. Create the reference if necessary.
/// Also return the WebAssembly type of the global. /// Also return the WebAssembly type of the global.
pub fn get_global<FE: FuncEnvironment + ?Sized>( pub(crate) fn get_global<FE: FuncEnvironment + ?Sized>(
&mut self, &mut self,
func: &mut ir::Function, func: &mut ir::Function,
index: u32, index: u32,
@@ -323,7 +315,7 @@ impl TranslationState {
/// Get the `Heap` reference that should be used to access linear memory `index`. /// Get the `Heap` reference that should be used to access linear memory `index`.
/// Create the reference if necessary. /// Create the reference if necessary.
pub fn get_heap<FE: FuncEnvironment + ?Sized>( pub(crate) fn get_heap<FE: FuncEnvironment + ?Sized>(
&mut self, &mut self,
func: &mut ir::Function, func: &mut ir::Function,
index: u32, index: u32,
@@ -338,7 +330,7 @@ impl TranslationState {
/// Get the `Table` reference that should be used to access table `index`. /// Get the `Table` reference that should be used to access table `index`.
/// Create the reference if necessary. /// Create the reference if necessary.
pub fn get_table<FE: FuncEnvironment + ?Sized>( pub(crate) fn get_table<FE: FuncEnvironment + ?Sized>(
&mut self, &mut self,
func: &mut ir::Function, func: &mut ir::Function,
index: u32, index: u32,
@@ -355,7 +347,7 @@ impl TranslationState {
/// `index`. Also return the number of WebAssembly arguments in the signature. /// `index`. Also return the number of WebAssembly arguments in the signature.
/// ///
/// Create the signature if necessary. /// Create the signature if necessary.
pub fn get_indirect_sig<FE: FuncEnvironment + ?Sized>( pub(crate) fn get_indirect_sig<FE: FuncEnvironment + ?Sized>(
&mut self, &mut self,
func: &mut ir::Function, func: &mut ir::Function,
index: u32, index: u32,
@@ -375,7 +367,7 @@ impl TranslationState {
/// `index`. Also return the number of WebAssembly arguments in the signature. /// `index`. Also return the number of WebAssembly arguments in the signature.
/// ///
/// Create the function reference if necessary. /// Create the function reference if necessary.
pub fn get_direct_func<FE: FuncEnvironment + ?Sized>( pub(crate) fn get_direct_func<FE: FuncEnvironment + ?Sized>(
&mut self, &mut self,
func: &mut ir::Function, func: &mut ir::Function,
index: u32, index: u32,