cranelift: Add heap support to the interpreter (#3302)
* cranelift: Add heaps to interpreter * cranelift: Add RunTest Environment mechanism to test interpret * cranelift: Remove unused `MemoryError` * cranelift: Add docs for `State::resolve_global_value` * cranelift: Rename heap tests * cranelift: Refactor heap address resolution * Fix typos and clarify docs (thanks @cfallin)
This commit is contained in:
@@ -3,10 +3,11 @@
|
||||
//! The `run` test command compiles each function on the host machine and executes it
|
||||
|
||||
use crate::function_runner::SingleFunctionCompiler;
|
||||
use crate::runtest_environment::RuntestEnvironment;
|
||||
use crate::runtest_environment::{HeapMemory, RuntestEnvironment};
|
||||
use crate::subtest::{Context, SubTest};
|
||||
use cranelift_codegen::data_value::DataValue;
|
||||
use cranelift_codegen::ir;
|
||||
use cranelift_codegen::ir::ArgumentPurpose;
|
||||
use cranelift_codegen::ir::Type;
|
||||
use cranelift_reader::parse_run_command;
|
||||
use cranelift_reader::TestCommand;
|
||||
use log::trace;
|
||||
@@ -64,25 +65,13 @@ impl SubTest for TestRun {
|
||||
let compiled_fn = compiler.compile(func.clone().into_owned())?;
|
||||
command
|
||||
.run(|_, run_args| {
|
||||
let runtime_struct = test_env.runtime_struct();
|
||||
|
||||
let first_arg_is_vmctx = func
|
||||
.signature
|
||||
.params
|
||||
.first()
|
||||
.map(|p| p.purpose == ArgumentPurpose::VMContext)
|
||||
.unwrap_or(false);
|
||||
|
||||
if !first_arg_is_vmctx && test_env.is_active() {
|
||||
return Err(concat!(
|
||||
"This test requests a heap, but the first argument is not `i64 vmctx`.\n",
|
||||
"See docs/testing.md for more info on using heap annotations."
|
||||
).to_string());
|
||||
}
|
||||
test_env.validate_signature(&func)?;
|
||||
let (_heaps, _ctx_struct, vmctx_ptr) =
|
||||
build_vmctx_struct(&test_env, context.isa.unwrap().pointer_type());
|
||||
|
||||
let mut args = Vec::with_capacity(run_args.len());
|
||||
if test_env.is_active() {
|
||||
args.push(runtime_struct.pointer(context.isa.unwrap().pointer_type()));
|
||||
args.push(vmctx_ptr);
|
||||
}
|
||||
args.extend_from_slice(run_args);
|
||||
|
||||
@@ -94,3 +83,24 @@ impl SubTest for TestRun {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Build a VMContext struct with the layout described in docs/testing.md.
|
||||
pub fn build_vmctx_struct(
|
||||
test_env: &RuntestEnvironment,
|
||||
ptr_ty: Type,
|
||||
) -> (Vec<HeapMemory>, Vec<u64>, DataValue) {
|
||||
let heaps = test_env.allocate_memory();
|
||||
|
||||
let context_struct: Vec<u64> = heaps
|
||||
.iter()
|
||||
.flat_map(|heap| [heap.as_ptr(), heap.as_ptr().wrapping_add(heap.len())])
|
||||
.map(|p| p as usize as u64)
|
||||
.collect();
|
||||
|
||||
let ptr = context_struct.as_ptr() as usize as i128;
|
||||
let ptr_dv =
|
||||
DataValue::from_integer(ptr, ptr_ty).expect("Failed to cast pointer to native target size");
|
||||
|
||||
// Return all these to make sure we don't deallocate the heaps too early
|
||||
(heaps, context_struct, ptr_dv)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user