Add FuncEnvironment trait.

This trait is used to provide the environment necessary to translate a
single WebAssembly function without having other global data structures
for the WebAssembly module.

The WasmRuntime trait extends the FuncEnvironment trait for those uses
that want to parse a whole WebAssembly module.

- Change the handling of WebAssembly globals to use the FuncEnvironment
  trait as well as the new GlobalVar infrastructure in Cretonne. The
  runtime is not consulted on the translation of each
  get_global/get_global instruction. Instead it gets to create the
  GlobalVar declaration in the function preamble the first time the
  global is used.

- Change the handling of heap load/store instructions to use the new
  Heap infrastructure in Cretonne. The runtime is called to create the
  Heap declaration in the preamble. It is not involved in individual
  load/store instructions.
This commit is contained in:
Jakob Stoklund Olesen
2017-09-05 13:11:35 -07:00
parent 19c8ba5021
commit 0ac1d0dd94
6 changed files with 240 additions and 190 deletions

View File

@@ -4,6 +4,9 @@
//! value and control stacks during the translation of a single function.
use cretonne::ir::{self, Ebb, Inst, Type, Value};
use runtime::{FuncEnvironment, GlobalValue};
use std::collections::HashMap;
use translation_utils::{GlobalIndex, MemoryIndex};
/// A control stack frame can be an `if`, a `block` or a `loop`, each one having the following
/// fields:
@@ -104,6 +107,12 @@ pub struct TranslationState {
pub control_stack: Vec<ControlStackFrame>,
pub phantom_unreachable_stack_depth: usize,
pub real_unreachable_stack_depth: usize,
// Map of global variables that have already been created by `FuncEnvironment::make_global`.
globals: HashMap<GlobalIndex, GlobalValue>,
// Map of heaps that have been created by `FuncEnvironment::make_heap`.
heaps: HashMap<MemoryIndex, ir::Heap>,
}
impl TranslationState {
@@ -113,6 +122,8 @@ impl TranslationState {
control_stack: Vec::new(),
phantom_unreachable_stack_depth: 0,
real_unreachable_stack_depth: 0,
globals: HashMap::new(),
heaps: HashMap::new(),
}
}
@@ -121,6 +132,8 @@ impl TranslationState {
self.control_stack.clear();
self.phantom_unreachable_stack_depth = 0;
self.real_unreachable_stack_depth = 0;
self.globals.clear();
self.heaps.clear();
}
/// Initialize the state for compiling a function with the given signature.
@@ -211,3 +224,35 @@ impl TranslationState {
}
}
}
/// Methods for handling entity references.
impl TranslationState {
/// Get the `GlobalVar` reference that should be used to access the global variable `index`.
/// Create the reference if necessary.
/// Also return the WebAssembly type of the global.
pub fn get_global<FE: FuncEnvironment + ?Sized>(
&mut self,
func: &mut ir::Function,
index: u32,
environ: &FE,
) -> GlobalValue {
let index = index as GlobalIndex;
*self.globals.entry(index).or_insert_with(
|| environ.make_global(func, index),
)
}
/// Get the `Heap` reference that should be used to access linear memory `index`.
/// Create the reference if necessary.
pub fn get_heap<FE: FuncEnvironment + ?Sized>(
&mut self,
func: &mut ir::Function,
index: u32,
environ: &FE,
) -> ir::Heap {
let index = index as MemoryIndex;
*self.heaps.entry(index).or_insert_with(
|| environ.make_heap(func, index),
)
}
}