mirror of
https://github.com/fluencelabs/wasmer
synced 2025-05-05 07:12:13 +00:00
Operator::Br and control stack fixes
This commit is contained in:
parent
61c83507a4
commit
aaabbf169c
@ -79,7 +79,6 @@ pub struct X64FunctionCode {
|
|||||||
id: usize,
|
id: usize,
|
||||||
begin_label: DynamicLabel,
|
begin_label: DynamicLabel,
|
||||||
begin_offset: AssemblyOffset,
|
begin_offset: AssemblyOffset,
|
||||||
cleanup_label: DynamicLabel,
|
|
||||||
assembler: Option<Assembler>,
|
assembler: Option<Assembler>,
|
||||||
returns: Vec<WpType>,
|
returns: Vec<WpType>,
|
||||||
locals: Vec<Local>,
|
locals: Vec<Local>,
|
||||||
@ -170,13 +169,12 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext> for X64ModuleCode
|
|||||||
; => begin_label
|
; => begin_label
|
||||||
; push rbp
|
; push rbp
|
||||||
; mov rbp, rsp
|
; mov rbp, rsp
|
||||||
//; int 3
|
; int 3
|
||||||
);
|
);
|
||||||
let code = X64FunctionCode {
|
let code = X64FunctionCode {
|
||||||
id: self.functions.len(),
|
id: self.functions.len(),
|
||||||
begin_label: begin_label,
|
begin_label: begin_label,
|
||||||
begin_offset: begin_offset,
|
begin_offset: begin_offset,
|
||||||
cleanup_label: assembler.new_dynamic_label(),
|
|
||||||
assembler: Some(assembler),
|
assembler: Some(assembler),
|
||||||
returns: vec![],
|
returns: vec![],
|
||||||
locals: vec![],
|
locals: vec![],
|
||||||
@ -351,6 +349,39 @@ impl X64FunctionCode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn emit_pop_into_ax(
|
||||||
|
assembler: &mut Assembler,
|
||||||
|
value_stack: &mut ValueStack,
|
||||||
|
) -> Result<(), CodegenError> {
|
||||||
|
let val = value_stack.pop()?;
|
||||||
|
match val.location {
|
||||||
|
ValueLocation::Register(x) => {
|
||||||
|
let reg = Register::from_scratch_reg(x);
|
||||||
|
dynasm!(
|
||||||
|
assembler
|
||||||
|
; mov rax, Rq(reg as u8)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ValueLocation::Stack => {
|
||||||
|
if is_dword(get_size_of_type(&val.ty)?) {
|
||||||
|
dynasm!(
|
||||||
|
assembler
|
||||||
|
; mov eax, [rsp]
|
||||||
|
; add rsp, 4
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
dynasm!(
|
||||||
|
assembler
|
||||||
|
; mov rax, [rsp]
|
||||||
|
; add rsp, 8
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn emit_leave_frame(
|
fn emit_leave_frame(
|
||||||
assembler: &mut Assembler,
|
assembler: &mut Assembler,
|
||||||
frame: &ControlFrame,
|
frame: &ControlFrame,
|
||||||
@ -379,30 +410,12 @@ impl X64FunctionCode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ty) = ret_ty {
|
if let Some(ty) = ret_ty {
|
||||||
let ret = value_stack.pop()?;
|
if value_stack.values.iter().last().map(|x| x.ty) != ret_ty {
|
||||||
match ret.location {
|
return Err(CodegenError {
|
||||||
ValueLocation::Register(x) => {
|
message: "value type != return type",
|
||||||
dynasm!(
|
});
|
||||||
assembler
|
|
||||||
; mov rax, Rq(x)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ValueLocation::Stack => {
|
|
||||||
if is_dword(get_size_of_type(&ty)?) {
|
|
||||||
dynasm!(
|
|
||||||
assembler
|
|
||||||
; mov eax, [rsp]
|
|
||||||
; add rsp, 4
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
dynasm!(
|
|
||||||
assembler
|
|
||||||
; mov rax, [rsp]
|
|
||||||
; add rsp, 8
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Self::emit_pop_into_ax(assembler, value_stack)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -741,22 +754,19 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
Operator::Return => match self.returns.len() {
|
Operator::Return => match self.returns.len() {
|
||||||
0 => {}
|
0 => {}
|
||||||
1 => {
|
1 => {
|
||||||
let val = self.value_stack.pop()?;
|
if self.value_stack.values.iter().last().map(|x| x.ty) != Some(self.returns[0])
|
||||||
let ty = self.returns[0];
|
{
|
||||||
let reg = val.location.get_register()?;
|
return Err(CodegenError {
|
||||||
if is_dword(get_size_of_type(&ty)?) {
|
message: "self.value_stack.last().cloned() != Some(self.returns[0])",
|
||||||
dynasm!(
|
});
|
||||||
assembler
|
|
||||||
; mov eax, Rd(Register::from_scratch_reg(reg) as u8)
|
|
||||||
; jmp =>self.cleanup_label
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
dynasm!(
|
|
||||||
assembler
|
|
||||||
; mov rax, Rq(Register::from_scratch_reg(reg) as u8)
|
|
||||||
; jmp =>self.cleanup_label
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
Self::emit_pop_into_ax(assembler, &mut self.value_stack)?;
|
||||||
|
dynasm!(
|
||||||
|
assembler
|
||||||
|
; mov rsp, rbp
|
||||||
|
; pop rbp
|
||||||
|
; ret
|
||||||
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(CodegenError {
|
return Err(CodegenError {
|
||||||
@ -771,6 +781,14 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
&mut self.value_stack,
|
&mut self.value_stack,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
Operator::Br { relative_depth } => {
|
||||||
|
Self::emit_jmp(
|
||||||
|
assembler,
|
||||||
|
self.control_stack.as_ref().unwrap(),
|
||||||
|
&mut self.value_stack,
|
||||||
|
relative_depth as usize,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -782,39 +800,16 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
dynasm!(
|
dynasm!(
|
||||||
assembler
|
assembler
|
||||||
; ud2
|
; ud2
|
||||||
; => self.cleanup_label
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if self.returns.len() == 1 {
|
if self.value_stack.values.len() != 0
|
||||||
if self.value_stack.values.len() != 1 {
|
|| self.control_stack.as_ref().unwrap().frames.len() != 0
|
||||||
return Err(CodegenError {
|
{
|
||||||
message: "returns.len() != value_stack.values.len()",
|
return Err(CodegenError {
|
||||||
});
|
message: "control/value stack not empty at end of function",
|
||||||
}
|
});
|
||||||
let value_info = self.value_stack.pop()?;
|
|
||||||
if value_info.ty != self.returns[0] {
|
|
||||||
return Err(CodegenError {
|
|
||||||
message: "return type mismatch",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if let ValueLocation::Register(x) = value_info.location {
|
|
||||||
let reg = Register::from_scratch_reg(x);
|
|
||||||
dynasm!(
|
|
||||||
assembler
|
|
||||||
; mov rax, Rq(reg as u8)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
unreachable!();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dynasm!(
|
|
||||||
assembler
|
|
||||||
; mov rsp, rbp
|
|
||||||
; pop rbp
|
|
||||||
; ret
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user