jsonpiler 0.9.3

a Json syntax programming language for Windows
Documentation
use crate::prelude::*;
impl Jsonpiler {
  pub(crate) fn mov_args_json(
    &mut self,
    idx: u32,
    scope: &mut Scope,
    arg: WithPos<Json>,
    copy: bool,
  ) -> ErrOR<()> {
    let reg = *ARG_REGS.get(idx as usize).unwrap_or(&Rax);
    if !copy {
      scope.extend(&self.mov_json(reg, arg, None)?);
      if reg == Rax {
        scope.push(mov_q(Args(i32::try_from(idx + 1)?), Rax));
      }
      return Ok(());
    }
    if arg.val.as_type() != StrT {
      scope.extend(&self.mov_json(reg, arg, Some(scope.id))?);
      if reg == Rax {
        scope.push(mov_q(Args(i32::try_from(idx + 1)?), Rax));
      }
      return Ok(());
    }
    let tmp = scope.alloc(0x20, 8)?;
    for (tmp_idx, tmp_reg) in ARG_REGS.iter().enumerate() {
      if *tmp_reg != reg {
        scope.push(mov_q(Local(Tmp, tmp + i32::try_from(tmp_idx * 8)?), *tmp_reg));
      }
    }
    scope.extend(&self.mov_json(reg, arg, Some(scope.id))?);
    if reg == Rax {
      scope.push(mov_q(Args(i32::try_from(idx + 1)?), Rax));
    }
    for (tmp_idx, tmp_reg) in ARG_REGS.iter().enumerate() {
      if *tmp_reg != reg {
        scope.push(mov_q(*tmp_reg, Local(Tmp, tmp + i32::try_from(tmp_idx * 8)?)));
      }
    }
    scope.free(tmp, Size(0x20));
    Ok(())
  }
  pub(crate) fn mov_float_xmm(
    &mut self,
    xmm: Register,
    tmp: Register,
    float: Bind<f64>,
  ) -> Vec<Inst> {
    match float {
      Lit(lit) => vec![MovSdM(xmm, self.global_q(lit.to_bits()).0)],
      Var(memory) => mov_memory_xmm(xmm, tmp, memory),
    }
  }
  pub(crate) fn mov_json(
    &mut self,
    dst: Register,
    src: WithPos<Json>,
    copy: Option<LabelId>,
  ) -> ErrOR<Vec<Inst>> {
    match src.val {
      Null(_) => Ok(vec![Clear(dst)]),
      Bool(boolean) => Ok(mov_bool(dst, boolean)),
      Int(int) => Ok(mov_int(dst, int)),
      Float(float) => Ok(mov_float_reg(dst, float)),
      Str(string) => Ok(if let Some(caller) = copy {
        vec![self.mov_str(Rcx, string), Call(self.copy_str(caller)?), mov_q(dst, Rax)]
      } else {
        vec![self.mov_str(dst, string)]
      }),
      Array(_) | Object(_) => err!(src.pos, UnsupportedType(src.val.describe())),
    }
  }
  pub(crate) fn mov_str(&mut self, dst: Register, string: Bind<String>) -> Inst {
    match string {
      Lit(lit) => LeaRM(dst, Global(self.global_str(lit))),
      Var(Memory(addr, _)) => mov_q(dst, addr),
    }
  }
}
pub(crate) fn mov_bool(dst: Register, boolean: Bind<bool>) -> Vec<Inst> {
  match boolean {
    Lit(lit) => vec![mov_b(dst, bool2byte(lit))],
    Var(memory) => mov_memory(dst, memory),
  }
}
pub(crate) fn mov_float_reg(dst: Register, float: Bind<f64>) -> Vec<Inst> {
  match float {
    Lit(lit) => vec![mov_q(dst, lit.to_bits())],
    Var(memory) => mov_memory(dst, memory),
  }
}
pub(crate) fn mov_int(dst: Register, int: Bind<i64>) -> Vec<Inst> {
  match int {
    Lit(lit) => vec![mov_imm(dst, lit)],
    Var(memory) => mov_memory(dst, memory),
  }
}
pub(crate) fn mov_imm(dst: Register, qword: i64) -> Inst {
  match qword {
    0 => Clear(dst),
    _ => {
      if let Ok(dword) = i32::try_from(qword)
        && qword.is_positive()
      {
        mov_d(dst, dword.cast_unsigned())
      } else {
        mov_q(dst, qword.cast_unsigned())
      }
    }
  }
}
pub(crate) fn mov_q<T: Into<Operand<u64>>, U: Into<Operand<u64>>>(dst: T, src: U) -> Inst {
  MovQQ((dst.into(), src.into()))
}
pub(crate) fn mov_d<T: Into<Operand<u32>>, U: Into<Operand<u32>>>(dst: T, src: U) -> Inst {
  MovDD((dst.into(), src.into()))
}
pub(crate) fn mov_b<T: Into<Operand<u8>>, U: Into<Operand<u8>>>(dst: T, src: U) -> Inst {
  MovBB((dst.into(), src.into()))
}
pub(crate) fn ret_memory(memory: Memory, tmp: Register, src: Register) -> Vec<Inst> {
  match memory {
    Memory(addr, Size(size)) => vec![if size == 1 { mov_b(addr, src) } else { mov_q(addr, src) }],
    Memory(addr, Heap(None)) => vec![mov_q(addr, src)],
    Memory(addr, Heap(Some(size))) => {
      vec![mov_q(tmp, addr), if size == 1 { mov_b(Ref(tmp), src) } else { mov_q(Ref(tmp), src) }]
    }
  }
}
pub(crate) fn mov_memory(dst: Register, memory: Memory) -> Vec<Inst> {
  match memory {
    Memory(addr, Size(size)) => vec![if size == 1 { mov_b(dst, addr) } else { mov_q(dst, addr) }],
    Memory(addr, Heap(None)) => vec![mov_q(dst, addr)],
    Memory(addr, Heap(Some(size))) => {
      vec![mov_q(dst, addr), if size == 1 { mov_b(dst, Ref(dst)) } else { mov_q(dst, Ref(dst)) }]
    }
  }
}
pub(crate) fn mov_memory_xmm(xmm: Register, tmp: Register, memory: Memory) -> Vec<Inst> {
  match memory {
    Memory(addr, Size(_) | Heap(None)) => vec![MovSdM(xmm, addr)],
    Memory(addr, Heap(Some(_))) => vec![mov_q(tmp, addr), MovSdRef(xmm, tmp)],
  }
}
pub(crate) fn ret_memory_xmm(memory: Memory, tmp: Register, xmm: Register) -> Vec<Inst> {
  match memory {
    Memory(addr, Size(_) | Heap(None)) => vec![MovMSd(addr, xmm)],
    Memory(addr, Heap(Some(_))) => vec![mov_q(tmp, addr), MovRefSd(tmp, xmm)],
  }
}