Get most spectests passing

This commit is contained in:
Lachlan Sneff
2019-01-17 13:09:05 -08:00
parent c74eed8a06
commit 1dbbaa30b6
10 changed files with 316 additions and 101 deletions

View File

@ -4,7 +4,6 @@ use cranelift_codegen::{
ir::{self, InstBuilder},
isa,
};
use cranelift_entity::EntityRef;
use cranelift_wasm::{self, FuncEnvironment, ModuleEnvironment};
use wasmer_runtime::{
memory::LinearMemory,
@ -105,7 +104,6 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
});
let offset = imported_global_index.index() * vm::ImportedGlobal::size() as usize;
let imported_global_addr = func.create_global_value(ir::GlobalValueData::IAddImm {
base: imported_globals_base_addr,
offset: (offset as i64).into(),
@ -282,7 +280,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
LocalOrImport::Import(imported_table_index) => {
let imported_tables_base = func.create_global_value(ir::GlobalValueData::Load {
base: vmctx,
offset: (vm::Ctx::offset_imported_memories() as i32).into(),
offset: (vm::Ctx::offset_imported_tables() as i32).into(),
global_type: ptr_type,
readonly: true,
});
@ -525,9 +523,9 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
fn translate_memory_grow(
&mut self,
mut pos: FuncCursor,
index: cranelift_wasm::MemoryIndex,
clif_mem_index: cranelift_wasm::MemoryIndex,
_heap: ir::Heap,
val: ir::Value,
by_value: ir::Value,
) -> cranelift_wasm::WasmResult<ir::Value> {
let signature = pos.func.import_signature(ir::Signature {
call_conv: self.target_config().default_call_conv,
@ -539,26 +537,42 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
returns: vec![ir::AbiParam::new(ir::types::I32)],
});
let grow_mem_func = pos.func.import_function(ir::ExtFuncData {
// `ir::ExternalName` for static_grow_memory`
name: ir::ExternalName::user(1, 0),
let mem_index: MemoryIndex = Converter(clif_mem_index).into();
let (name, mem_index) = match mem_index.local_or_import(self.env.module) {
LocalOrImport::Local(local_mem_index) => {
(
// local_static_memory_grow
ir::ExternalName::user(1, 0),
local_mem_index.index(),
)
}
LocalOrImport::Import(imported_mem_index) => {
(
// imported_static_memory_grow
ir::ExternalName::user(1, 2),
imported_mem_index.index(),
)
}
};
let mem_grow_func = pos.func.import_function(ir::ExtFuncData {
name,
signature,
colocated: false,
});
// Create a memory index value.
let memory_index = pos.ins().iconst(ir::types::I32, index.index() as i64);
let const_mem_index = pos.ins().iconst(ir::types::I32, mem_index as i64);
// Create a VMContext value.
let vmctx = pos
.func
.special_param(ir::ArgumentPurpose::VMContext)
.expect("missing vmctx parameter");
// Insert call instructions for `grow_memory`.
let call_inst = pos.ins().call(grow_mem_func, &[memory_index, val, vmctx]);
let call_inst = pos
.ins()
.call(mem_grow_func, &[const_mem_index, by_value, vmctx]);
// Return value.
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
}
@ -570,9 +584,40 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
fn translate_memory_size(
&mut self,
mut pos: FuncCursor,
index: cranelift_wasm::MemoryIndex,
clif_mem_index: cranelift_wasm::MemoryIndex,
_heap: ir::Heap,
) -> cranelift_wasm::WasmResult<ir::Value> {
// let signature = pos.func.import_signature(ir::Signature {
// call_conv: self.target_config().default_call_conv,
// params: vec![
// ir::AbiParam::new(ir::types::I32),
// ir::AbiParam::special(self.pointer_type(), ir::ArgumentPurpose::VMContext),
// ],
// returns: vec![ir::AbiParam::new(ir::types::I32)],
// });
// let size_mem_func = pos.func.import_function(ir::ExtFuncData {
// // `ir::ExternalName` for static_grow_memory`
// name: ir::ExternalName::user(1, 1),
// signature,
// colocated: false,
// });
// // Create a memory index value.
// let memory_index = pos.ins().iconst(ir::types::I32, index.index() as i64);
// // Create a VMContext value.
// let vmctx = pos
// .func
// .special_param(ir::ArgumentPurpose::VMContext)
// .expect("missing vmctx parameter");
// // Insert call instructions for `grow_memory`.
// let call_inst = pos.ins().call(size_mem_func, &[memory_index, vmctx]);
// // Return value.
// Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
let signature = pos.func.import_signature(ir::Signature {
call_conv: self.target_config().default_call_conv,
params: vec![
@ -582,26 +627,39 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
returns: vec![ir::AbiParam::new(ir::types::I32)],
});
let size_mem_func = pos.func.import_function(ir::ExtFuncData {
// `ir::ExternalName` for static_grow_memory`
name: ir::ExternalName::user(1, 1),
let mem_index: MemoryIndex = Converter(clif_mem_index).into();
let (name, mem_index) = match mem_index.local_or_import(self.env.module) {
LocalOrImport::Local(local_mem_index) => {
(
// local_static_memory_size
ir::ExternalName::user(1, 1),
local_mem_index.index(),
)
}
LocalOrImport::Import(imported_mem_index) => {
(
// imported_static_memory_size
ir::ExternalName::user(1, 3),
imported_mem_index.index(),
)
}
};
let mem_grow_func = pos.func.import_function(ir::ExtFuncData {
name,
signature,
colocated: false,
});
// Create a memory index value.
let memory_index = pos.ins().iconst(ir::types::I32, index.index() as i64);
// Create a VMContext value.
let const_mem_index = pos.ins().iconst(ir::types::I32, mem_index as i64);
let vmctx = pos
.func
.special_param(ir::ArgumentPurpose::VMContext)
.expect("missing vmctx parameter");
// Insert call instructions for `grow_memory`.
let call_inst = pos.ins().call(size_mem_func, &[memory_index, vmctx]);
let call_inst = pos.ins().call(mem_grow_func, &[const_mem_index, vmctx]);
// Return value.
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
}
}

View File

@ -20,14 +20,21 @@ pub struct Relocation {
pub target: RelocationType,
}
#[derive(Debug, Clone, Copy)]
pub enum VmCall {
LocalStaticMemoryGrow,
LocalStaticMemorySize,
ImportedStaticMemoryGrow,
ImportedStaticMemorySize,
}
/// Specify the type of relocation
#[derive(Debug, Clone)]
pub enum RelocationType {
Normal(LocalFuncIndex),
Intrinsic(String),
LibCall(LibCall),
StaticGrowMemory,
StaticCurrentMemory,
VmCall(VmCall),
}
/// Implementation of a relocation sink that just saves all the information for later
@ -69,11 +76,13 @@ impl binemit::RelocSink for RelocSink {
namespace: 1,
index,
} => {
let target = match index {
0 => RelocationType::StaticGrowMemory,
1 => RelocationType::StaticCurrentMemory,
let target = RelocationType::VmCall(match index {
0 => VmCall::LocalStaticMemoryGrow,
1 => VmCall::LocalStaticMemorySize,
2 => VmCall::ImportedStaticMemoryGrow,
3 => VmCall::ImportedStaticMemorySize,
_ => unimplemented!(),
};
});
self.func_relocs.push(Relocation {
reloc,
offset,

View File

@ -1,5 +1,5 @@
use crate::libcalls;
use crate::relocation::{Reloc, RelocSink, Relocation, RelocationType, TrapSink};
use crate::relocation::{Reloc, RelocSink, Relocation, RelocationType, TrapSink, VmCall};
use byteorder::{ByteOrder, LittleEndian};
use cranelift_codegen::{ir, isa, Context};
use std::mem;
@ -87,8 +87,6 @@ impl FuncResolverBuilder {
// called in this way.
self.resolver.lookup(local_func_index).unwrap().as_ptr() as isize
}
RelocationType::StaticCurrentMemory => vmcalls::memory_size as isize,
RelocationType::StaticGrowMemory => vmcalls::memory_grow_static as isize,
RelocationType::LibCall(libcall) => match libcall {
ir::LibCall::CeilF32 => libcalls::ceilf32 as isize,
ir::LibCall::FloorF32 => libcalls::floorf32 as isize,
@ -106,6 +104,16 @@ impl FuncResolverBuilder {
RelocationType::Intrinsic(ref name) => {
panic!("unexpected intrinsic {}", name);
}
RelocationType::VmCall(vmcall) => match vmcall {
VmCall::LocalStaticMemoryGrow => vmcalls::local_static_memory_grow as _,
VmCall::LocalStaticMemorySize => vmcalls::local_static_memory_size as _,
VmCall::ImportedStaticMemoryGrow => {
vmcalls::imported_static_memory_grow as _
}
VmCall::ImportedStaticMemorySize => {
vmcalls::imported_static_memory_size as _
}
},
};
// We need the address of the current function