mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-13 22:25:40 +00:00
TwoHalves & trying to get cowsay to compile again
This commit is contained in:
parent
0133b92bec
commit
cc4f0e31a6
@ -1,4 +1,4 @@
|
|||||||
use super::stackmap::{self, StackmapRegistry};
|
use super::stackmap::{self, StackmapRegistry, StkMapRecord};
|
||||||
use crate::intrinsics::Intrinsics;
|
use crate::intrinsics::Intrinsics;
|
||||||
use inkwell::{
|
use inkwell::{
|
||||||
memory_buffer::MemoryBuffer,
|
memory_buffer::MemoryBuffer,
|
||||||
@ -18,6 +18,7 @@ use std::{
|
|||||||
ptr::{self, NonNull},
|
ptr::{self, NonNull},
|
||||||
slice, str,
|
slice, str,
|
||||||
sync::{Arc, Once},
|
sync::{Arc, Once},
|
||||||
|
collections::BTreeMap,
|
||||||
};
|
};
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::{
|
backend::{
|
||||||
@ -304,7 +305,7 @@ impl LLVMBackend {
|
|||||||
};
|
};
|
||||||
if raw_stackmap.len() > 0 {
|
if raw_stackmap.len() > 0 {
|
||||||
let map = stackmap::StackMap::parse(raw_stackmap).unwrap();
|
let map = stackmap::StackMap::parse(raw_stackmap).unwrap();
|
||||||
eprintln!("{:?}", map);
|
println!("{:?}", map);
|
||||||
|
|
||||||
let (code_ptr, code_size) = unsafe {
|
let (code_ptr, code_size) = unsafe {
|
||||||
(
|
(
|
||||||
@ -316,10 +317,16 @@ impl LLVMBackend {
|
|||||||
local_functions: Default::default(),
|
local_functions: Default::default(),
|
||||||
total_size: code_size,
|
total_size: code_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut map_records: BTreeMap<usize, &StkMapRecord> = BTreeMap::new();
|
||||||
|
for r in &map.stk_map_records {
|
||||||
|
map_records.insert(r.patchpoint_id as usize, r);
|
||||||
|
}
|
||||||
|
|
||||||
let mut map_record_idx: usize = 0;
|
let mut map_record_idx: usize = 0;
|
||||||
for size_record in &map.stk_size_records {
|
for size_record in &map.stk_size_records {
|
||||||
for _ in 0..size_record.record_count {
|
for _ in 0..size_record.record_count as usize {
|
||||||
let map_record = &map.stk_map_records[map_record_idx];
|
let map_record = map_records.get(&map_record_idx).expect("map record not found");
|
||||||
let map_entry = &stackmaps.entries[map_record_idx];
|
let map_entry = &stackmaps.entries[map_record_idx];
|
||||||
assert_eq!(map_record.patchpoint_id, map_record_idx as u64);
|
assert_eq!(map_record.patchpoint_id, map_record_idx as u64);
|
||||||
map_record_idx += 1;
|
map_record_idx += 1;
|
||||||
|
@ -447,6 +447,26 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
|
|||||||
let ctx = CtxType::new(module_info, function, cache_builder);
|
let ctx = CtxType::new(module_info, function, cache_builder);
|
||||||
|
|
||||||
self.ctx = Some(ctx);
|
self.ctx = Some(ctx);
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut state = &mut self.state;
|
||||||
|
let builder = self.builder.as_ref().unwrap();
|
||||||
|
let intrinsics = self.intrinsics.as_ref().unwrap();
|
||||||
|
|
||||||
|
let mut stackmaps = self.stackmaps.borrow_mut();
|
||||||
|
emit_stack_map(
|
||||||
|
&intrinsics,
|
||||||
|
&builder,
|
||||||
|
self.index,
|
||||||
|
&mut *stackmaps,
|
||||||
|
StackmapEntryKind::FunctionHeader,
|
||||||
|
&self.locals,
|
||||||
|
&state,
|
||||||
|
::std::usize::MAX,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2582,20 +2602,6 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
|
|||||||
|
|
||||||
let local_func_index = self.functions.len();
|
let local_func_index = self.functions.len();
|
||||||
|
|
||||||
{
|
|
||||||
let mut stackmaps = self.stackmaps.borrow_mut();
|
|
||||||
emit_stack_map(
|
|
||||||
&intrinsics,
|
|
||||||
&builder,
|
|
||||||
local_func_index,
|
|
||||||
&mut *stackmaps,
|
|
||||||
StackmapEntryKind::FunctionHeader,
|
|
||||||
&locals,
|
|
||||||
&state,
|
|
||||||
::std::usize::MAX,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let code = LLVMFunctionCodeGenerator {
|
let code = LLVMFunctionCodeGenerator {
|
||||||
state,
|
state,
|
||||||
context: Some(context),
|
context: Some(context),
|
||||||
|
@ -74,7 +74,7 @@ impl StackmapEntry {
|
|||||||
map_record: &StkMapRecord,
|
map_record: &StkMapRecord,
|
||||||
msm: &mut ModuleStateMap,
|
msm: &mut ModuleStateMap,
|
||||||
) {
|
) {
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
enum RuntimeOrConstant {
|
enum RuntimeOrConstant {
|
||||||
Runtime(MachineValue),
|
Runtime(MachineValue),
|
||||||
Constant(u64),
|
Constant(u64),
|
||||||
@ -88,10 +88,9 @@ impl StackmapEntry {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(self.value_semantics.len(), map_record.locations.len());
|
assert_eq!(self.value_semantics.len(), map_record.locations.len());
|
||||||
assert!(size_record.stack_size % 8 == 0);
|
//assert!(size_record.stack_size % 8 == 0); // is this also aligned to 16 bytes?
|
||||||
|
|
||||||
let mut machine_stack_layout: Vec<MachineValue> =
|
let mut machine_stack_half_layout: Vec<MachineValue> = Vec::new();
|
||||||
vec![MachineValue::Undefined; (size_record.stack_size as usize) / 8];
|
|
||||||
let mut regs: Vec<(RegisterIndex, MachineValue)> = vec![];
|
let mut regs: Vec<(RegisterIndex, MachineValue)> = vec![];
|
||||||
let mut stack_constants: HashMap<usize, u64> = HashMap::new();
|
let mut stack_constants: HashMap<usize, u64> = HashMap::new();
|
||||||
|
|
||||||
@ -145,30 +144,38 @@ impl StackmapEntry {
|
|||||||
}
|
}
|
||||||
LocationType::Direct => match mv {
|
LocationType::Direct => match mv {
|
||||||
MachineValue::WasmLocal(_) => {
|
MachineValue::WasmLocal(_) => {
|
||||||
assert_eq!(loc.location_size, 8);
|
assert_eq!(loc.location_size, 8); // the pointer itself
|
||||||
assert!(loc.offset_or_small_constant < 0);
|
|
||||||
assert!(
|
assert!(
|
||||||
X64Register::from_dwarf_regnum(loc.dwarf_regnum).unwrap()
|
X64Register::from_dwarf_regnum(loc.dwarf_regnum).unwrap()
|
||||||
== X64Register::GPR(GPR::RBP)
|
== X64Register::GPR(GPR::RBP)
|
||||||
);
|
);
|
||||||
let stack_offset = ((-loc.offset_or_small_constant) % 8) as usize;
|
if loc.offset_or_small_constant >= 0 {
|
||||||
assert!(stack_offset > 0 && stack_offset <= machine_stack_layout.len());
|
eprintln!("XXX: {}", loc.offset_or_small_constant);
|
||||||
machine_stack_layout[stack_offset - 1] = mv;
|
}
|
||||||
|
assert!(loc.offset_or_small_constant < 0);
|
||||||
|
let stack_offset = ((-loc.offset_or_small_constant) / 4) as usize;
|
||||||
|
while stack_offset > machine_stack_half_layout.len() {
|
||||||
|
machine_stack_half_layout.push(MachineValue::Undefined);
|
||||||
|
}
|
||||||
|
assert!(stack_offset > 0 && stack_offset <= machine_stack_half_layout.len());
|
||||||
|
machine_stack_half_layout[stack_offset - 1] = mv;
|
||||||
}
|
}
|
||||||
_ => unreachable!(
|
_ => unreachable!(
|
||||||
"Direct location type is not expected for values other than local"
|
"Direct location type is not expected for values other than local"
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
LocationType::Indirect => {
|
LocationType::Indirect => {
|
||||||
assert_eq!(loc.location_size, 8);
|
|
||||||
assert!(loc.offset_or_small_constant < 0);
|
assert!(loc.offset_or_small_constant < 0);
|
||||||
assert!(
|
assert!(
|
||||||
X64Register::from_dwarf_regnum(loc.dwarf_regnum).unwrap()
|
X64Register::from_dwarf_regnum(loc.dwarf_regnum).unwrap()
|
||||||
== X64Register::GPR(GPR::RBP)
|
== X64Register::GPR(GPR::RBP)
|
||||||
);
|
);
|
||||||
let stack_offset = ((-loc.offset_or_small_constant) % 8) as usize;
|
let stack_offset = ((-loc.offset_or_small_constant) / 4) as usize;
|
||||||
assert!(stack_offset > 0 && stack_offset <= machine_stack_layout.len());
|
while stack_offset > machine_stack_half_layout.len() {
|
||||||
machine_stack_layout[stack_offset - 1] = mv;
|
machine_stack_half_layout.push(MachineValue::Undefined);
|
||||||
|
}
|
||||||
|
assert!(stack_offset > 0 && stack_offset <= machine_stack_half_layout.len());
|
||||||
|
machine_stack_half_layout[stack_offset - 1] = mv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,6 +183,26 @@ impl StackmapEntry {
|
|||||||
assert_eq!(wasm_stack.len(), self.stack_count);
|
assert_eq!(wasm_stack.len(), self.stack_count);
|
||||||
assert_eq!(wasm_locals.len(), self.local_count);
|
assert_eq!(wasm_locals.len(), self.local_count);
|
||||||
|
|
||||||
|
if machine_stack_half_layout.len() % 2 != 0 {
|
||||||
|
machine_stack_half_layout.push(MachineValue::Undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut machine_stack_layout: Vec<MachineValue> = Vec::with_capacity(machine_stack_half_layout.len() / 2);
|
||||||
|
|
||||||
|
for i in 0..machine_stack_half_layout.len() / 2 {
|
||||||
|
let left = &machine_stack_half_layout[i * 2];
|
||||||
|
let right = &machine_stack_half_layout[i * 2 + 1];
|
||||||
|
let only_left = match *right {
|
||||||
|
MachineValue::Undefined => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
if only_left {
|
||||||
|
machine_stack_layout.push(left.clone());
|
||||||
|
} else {
|
||||||
|
machine_stack_layout.push(MachineValue::TwoHalves(Box::new((right.clone(), left.clone()))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let diff = MachineStateDiff {
|
let diff = MachineStateDiff {
|
||||||
last: None,
|
last: None,
|
||||||
stack_push: machine_stack_layout,
|
stack_push: machine_stack_layout,
|
||||||
|
@ -35,7 +35,7 @@ pub struct MachineStateDiff {
|
|||||||
pub wasm_inst_offset: usize, // absolute value; not a diff.
|
pub wasm_inst_offset: usize, // absolute value; not a diff.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
pub enum MachineValue {
|
pub enum MachineValue {
|
||||||
Undefined,
|
Undefined,
|
||||||
Vmctx,
|
Vmctx,
|
||||||
@ -44,6 +44,7 @@ pub enum MachineValue {
|
|||||||
ExplicitShadow, // indicates that all values above this are above the shadow region
|
ExplicitShadow, // indicates that all values above this are above the shadow region
|
||||||
WasmStack(usize),
|
WasmStack(usize),
|
||||||
WasmLocal(usize),
|
WasmLocal(usize),
|
||||||
|
TwoHalves(Box<(MachineValue, MachineValue)>), // 32-bit values. TODO: optimize: add another type for inner "half" value to avoid boxing?
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -203,7 +204,7 @@ impl MachineState {
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(old.stack_values.iter())
|
.zip(old.stack_values.iter())
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|&(_, (&a, &b))| a != b)
|
.find(|&(_, (a, b))| a != b)
|
||||||
.map(|x| x.0)
|
.map(|x| x.0)
|
||||||
.unwrap_or(old.stack_values.len().min(self.stack_values.len()));
|
.unwrap_or(old.stack_values.len().min(self.stack_values.len()));
|
||||||
assert_eq!(self.register_values.len(), old.register_values.len());
|
assert_eq!(self.register_values.len(), old.register_values.len());
|
||||||
@ -212,15 +213,15 @@ impl MachineState {
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(old.register_values.iter())
|
.zip(old.register_values.iter())
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|&(_, (&a, &b))| a != b)
|
.filter(|&(_, (a, b))| a != b)
|
||||||
.map(|(i, (&a, _))| (RegisterIndex(i), a))
|
.map(|(i, (a, _))| (RegisterIndex(i), a.clone()))
|
||||||
.collect();
|
.collect();
|
||||||
let first_diff_wasm_stack_depth: usize = self
|
let first_diff_wasm_stack_depth: usize = self
|
||||||
.wasm_stack
|
.wasm_stack
|
||||||
.iter()
|
.iter()
|
||||||
.zip(old.wasm_stack.iter())
|
.zip(old.wasm_stack.iter())
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|&(_, (&a, &b))| a != b)
|
.find(|&(_, (a, b))| a != b)
|
||||||
.map(|x| x.0)
|
.map(|x| x.0)
|
||||||
.unwrap_or(old.wasm_stack.len().min(self.wasm_stack.len()));
|
.unwrap_or(old.wasm_stack.len().min(self.wasm_stack.len()));
|
||||||
MachineStateDiff {
|
MachineStateDiff {
|
||||||
@ -255,10 +256,10 @@ impl MachineStateDiff {
|
|||||||
state.stack_values.pop().unwrap();
|
state.stack_values.pop().unwrap();
|
||||||
}
|
}
|
||||||
for v in &x.stack_push {
|
for v in &x.stack_push {
|
||||||
state.stack_values.push(*v);
|
state.stack_values.push(v.clone());
|
||||||
}
|
}
|
||||||
for &(index, v) in &x.reg_diff {
|
for &(index, ref v) in &x.reg_diff {
|
||||||
state.register_values[index.0] = v;
|
state.register_values[index.0] = v.clone();
|
||||||
}
|
}
|
||||||
for _ in 0..x.wasm_stack_pop {
|
for _ in 0..x.wasm_stack_pop {
|
||||||
state.wasm_stack.pop().unwrap();
|
state.wasm_stack.pop().unwrap();
|
||||||
@ -488,6 +489,72 @@ pub mod x64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
MachineValue::TwoHalves(ref inner) => {
|
||||||
|
stack_offset -= 1;
|
||||||
|
// TODO: Cleanup
|
||||||
|
match inner.0 {
|
||||||
|
MachineValue::WasmStack(x) => {
|
||||||
|
match state.wasm_stack[x] {
|
||||||
|
WasmAbstractValue::Const(x) => {
|
||||||
|
assert!(x <= ::std::u32::MAX as u64);
|
||||||
|
stack[stack_offset] |= x;
|
||||||
|
}
|
||||||
|
WasmAbstractValue::Runtime => {
|
||||||
|
let v = f.stack[x].unwrap();
|
||||||
|
assert!(v <= ::std::u32::MAX as u64);
|
||||||
|
stack[stack_offset] |= v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MachineValue::WasmLocal(x) => {
|
||||||
|
stack_offset -= 1;
|
||||||
|
match fsm.locals[x] {
|
||||||
|
WasmAbstractValue::Const(x) => {
|
||||||
|
assert!(x <= ::std::u32::MAX as u64);
|
||||||
|
stack[stack_offset] |= x;
|
||||||
|
}
|
||||||
|
WasmAbstractValue::Runtime => {
|
||||||
|
let v = f.locals[x].unwrap();
|
||||||
|
assert!(v <= ::std::u32::MAX as u64);
|
||||||
|
stack[stack_offset] |= v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MachineValue::Undefined => {}
|
||||||
|
_ => unimplemented!("TwoHalves.0"),
|
||||||
|
}
|
||||||
|
match inner.1 {
|
||||||
|
MachineValue::WasmStack(x) => {
|
||||||
|
match state.wasm_stack[x] {
|
||||||
|
WasmAbstractValue::Const(x) => {
|
||||||
|
assert!(x <= ::std::u32::MAX as u64);
|
||||||
|
stack[stack_offset] |= x << 32;
|
||||||
|
}
|
||||||
|
WasmAbstractValue::Runtime => {
|
||||||
|
let v = f.stack[x].unwrap();
|
||||||
|
assert!(v <= ::std::u32::MAX as u64);
|
||||||
|
stack[stack_offset] |= v << 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MachineValue::WasmLocal(x) => {
|
||||||
|
stack_offset -= 1;
|
||||||
|
match fsm.locals[x] {
|
||||||
|
WasmAbstractValue::Const(x) => {
|
||||||
|
assert!(x <= ::std::u32::MAX as u64);
|
||||||
|
stack[stack_offset] |= x << 32;
|
||||||
|
}
|
||||||
|
WasmAbstractValue::Runtime => {
|
||||||
|
let v = f.locals[x].unwrap();
|
||||||
|
assert!(v <= ::std::u32::MAX as u64);
|
||||||
|
stack[stack_offset] |= v << 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MachineValue::Undefined => {}
|
||||||
|
_ => unimplemented!("TwoHalves.1"),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !got_explicit_shadow {
|
if !got_explicit_shadow {
|
||||||
@ -785,6 +852,30 @@ pub mod x64 {
|
|||||||
wasm_locals[idx] = Some(*stack);
|
wasm_locals[idx] = Some(*stack);
|
||||||
stack = stack.offset(1);
|
stack = stack.offset(1);
|
||||||
}
|
}
|
||||||
|
MachineValue::TwoHalves(ref inner) => {
|
||||||
|
let v = *stack;
|
||||||
|
stack = stack.offset(1);
|
||||||
|
match inner.0 {
|
||||||
|
MachineValue::WasmStack(idx) => {
|
||||||
|
wasm_stack[idx] = Some(v & 0xffffffffu64);
|
||||||
|
}
|
||||||
|
MachineValue::WasmLocal(idx) => {
|
||||||
|
wasm_locals[idx] = Some(v & 0xffffffffu64);
|
||||||
|
}
|
||||||
|
MachineValue::Undefined => {},
|
||||||
|
_ => unimplemented!("TwoHalves.0 (read)")
|
||||||
|
}
|
||||||
|
match inner.1 {
|
||||||
|
MachineValue::WasmStack(idx) => {
|
||||||
|
wasm_stack[idx] = Some(v >> 32);
|
||||||
|
}
|
||||||
|
MachineValue::WasmLocal(idx) => {
|
||||||
|
wasm_locals[idx] = Some(v >> 32);
|
||||||
|
}
|
||||||
|
MachineValue::Undefined => {},
|
||||||
|
_ => unimplemented!("TwoHalves.1 (read)")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stack = stack.offset(1); // RBP
|
stack = stack.offset(1); // RBP
|
||||||
|
Loading…
Reference in New Issue
Block a user