Strongly type scratch registers and fixed an unwinding issue.

This commit is contained in:
losfair 2019-03-05 00:23:49 +08:00
parent 2962fe25b6
commit fa61b66516
2 changed files with 20 additions and 9 deletions

View File

@ -1,5 +1,7 @@
use super::codegen::*; use super::codegen::*;
use super::stack::{ControlFrame, ControlStack, IfElseState, ValueInfo, ValueLocation, ValueStack}; use super::stack::{
ControlFrame, ControlStack, IfElseState, ScratchRegister, ValueInfo, ValueLocation, ValueStack,
};
use byteorder::{ByteOrder, LittleEndian}; use byteorder::{ByteOrder, LittleEndian};
use dynasmrt::{ use dynasmrt::{
x64::Assembler, AssemblyOffset, DynamicLabel, DynasmApi, DynasmLabelApi, ExecutableBuffer, x64::Assembler, AssemblyOffset, DynamicLabel, DynasmApi, DynasmLabelApi, ExecutableBuffer,
@ -85,9 +87,9 @@ pub enum Register {
} }
impl Register { impl Register {
pub fn from_scratch_reg(id: u8) -> Register { pub fn from_scratch_reg(sr: ScratchRegister) -> Register {
use self::Register::*; use self::Register::*;
match id { match sr.raw_id() {
0 => RDI, 0 => RDI,
1 => RSI, 1 => RSI,
2 => RDX, 2 => RDX,
@ -804,7 +806,7 @@ impl X64FunctionCode {
let reg = Register::from_scratch_reg(x); let reg = Register::from_scratch_reg(x);
dynasm!( dynasm!(
assembler assembler
; mov Rq(x as u8), rax ; mov Rq(reg as u8), rax
); );
} }
ValueLocation::Stack => { ValueLocation::Stack => {

View File

@ -56,10 +56,19 @@ pub struct ValueInfo {
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ValueLocation { pub enum ValueLocation {
Register(u8), Register(ScratchRegister),
Stack, Stack,
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct ScratchRegister(u8);
impl ScratchRegister {
pub fn raw_id(&self) -> u8 {
self.0
}
}
impl ValueLocation { impl ValueLocation {
pub fn is_register(&self) -> bool { pub fn is_register(&self) -> bool {
if let ValueLocation::Register(_) = *self { if let ValueLocation::Register(_) = *self {
@ -69,7 +78,7 @@ impl ValueLocation {
} }
} }
pub fn get_register(&self) -> Result<u8, CodegenError> { pub fn get_register(&self) -> Result<ScratchRegister, CodegenError> {
if let ValueLocation::Register(id) = *self { if let ValueLocation::Register(id) = *self {
Ok(id) Ok(id)
} else { } else {
@ -90,11 +99,11 @@ impl ValueStack {
fn next_location(&self, loc: &ValueLocation) -> ValueLocation { fn next_location(&self, loc: &ValueLocation) -> ValueLocation {
match *loc { match *loc {
ValueLocation::Register(x) => { ValueLocation::Register(ScratchRegister(x)) => {
if x >= self.num_regs - 1 { if x >= self.num_regs - 1 {
ValueLocation::Stack ValueLocation::Stack
} else { } else {
ValueLocation::Register(x + 1) ValueLocation::Register(ScratchRegister(x + 1))
} }
} }
ValueLocation::Stack => ValueLocation::Stack, ValueLocation::Stack => ValueLocation::Stack,
@ -106,7 +115,7 @@ impl ValueStack {
.values .values
.last() .last()
.map(|x| self.next_location(&x.location)) .map(|x| self.next_location(&x.location))
.unwrap_or(ValueLocation::Register(0)); .unwrap_or(ValueLocation::Register(ScratchRegister(0)));
self.values.push(ValueInfo { self.values.push(ValueInfo {
ty: ty, ty: ty,
location: loc, location: loc,