jsonpiler 0.10.4

a Json syntax programming language for Windows
Documentation
use crate::prelude::*;
impl Jsonpiler {
  pub(crate) fn copy_str(&mut self, caller: LabelId) -> ErrOR<LabelId> {
    const SIZE: i32 = 0x50;
    let id = symbol!(self, caller, COPY2HEAP);
    let heap = Global(self.symbols[HEAP]);
    let tmp_d = Local(Tmp, -0x08);
    let tmp_s = Local(Tmp, -0x10);
    let tmp_b = Local(Tmp, -0x18);
    let tmp_12 = Local(Tmp, -0x20);
    let insts = &[
      mov_q(tmp_d, Rdi),
      mov_q(tmp_s, Rsi),
      mov_q(tmp_b, Rbx),
      mov_q(tmp_12, R12),
      mov_q(Rdi, Rcx),
      mov_q(R12, Rdi),
      Clear(Rcx),
      DecR(Rcx),
      Clear(Rax),
      Custom(CLD_REPNE_SCASB),
      SubRR(Rdi, R12),
      mov_q(Rbx, Rdi),
      mov_q(Rcx, heap),
      mov_d(Rdx, 8),
      mov_q(R8, Rbx),
      CallApi(self.api(KERNEL32, "HeapAlloc")),
      IncMd(Global(self.symbols[LEAK_CNT])),
      mov_q(Rcx, Rbx),
      mov_q(Rdi, Rax),
      mov_q(Rsi, R12),
      Custom(CLD_REP_MOVSB),
      mov_q(Rdi, tmp_d),
      mov_q(Rsi, tmp_s),
      mov_q(Rbx, tmp_b),
      mov_q(R12, tmp_12),
    ];
    self.link_function(id, insts, SIZE);
    Ok(id)
  }
  pub(crate) fn get_int_to_str(&mut self, caller: LabelId) -> ErrOR<LabelId> {
    const SIZE: i32 = 0x50;
    let id = symbol!(self, caller, INT2STR);
    let count_end = self.id();
    let negative = self.id();
    let positive = self.id();
    let count_start = self.id();
    let write_start = self.id();
    let write_positive = self.id();
    let i64_min = self.id();
    let epilogue = self.id();
    let tmp_s = Local(Tmp, -0x08);
    let tmp_b = Local(Tmp, -0x10);
    let count = Local(Tmp, -0x1C);
    let is_neg = Local(Tmp, -0x1D);
    let i64_min_str = Global(self.global_str(i64::MIN.to_string()));
    let copy_str = self.copy_str(id)?;
    let insts = &[
      mov_q(tmp_s, Rsi),
      mov_q(tmp_b, Rbx),
      mov_q(Rsi, Rcx),
      mov_b(is_neg, 0),
      mov_d(count, 1),
      Clear(Rdx),
      LogicRR(Cmp, Rsi, Rdx),
      JCc(G, positive),
      JCc(Ne, negative),
      IncMd(count),
      Jmp(count_end),
      Lbl(negative),
      mov_b(is_neg, 0xFF),
      UnaryR(Neg, Rsi),
      LogicRR(Cmp, Rsi, Rcx),
      JCc(E, i64_min),
      IncMd(count),
      Jmp(positive),
      Lbl(i64_min),
      LeaRM(Rcx, i64_min_str),
      Call(copy_str),
      Jmp(epilogue),
      Lbl(positive),
      mov_q(Rax, Rsi),
      Lbl(count_start),
      mov_d(Rbx, 10),
      Custom(CQO),
      IDivR(Rbx),
      IncMd(count),
      LogicRR(Test, Rax, Rax),
      JCc(Ne, count_start),
      Lbl(count_end),
      mov_q(Rcx, Global(self.symbols[HEAP])),
      mov_d(Rdx, 8),
      mov_d(R8, count),
      CallApi(self.api(KERNEL32, "HeapAlloc")),
      IncMd(Global(self.symbols[LEAK_CNT])),
      mov_q(Rcx, Rax),
      mov_d(Rax, count),
      AddRR(Rcx, Rax),
      Clear(Rdx),
      DecR(Rcx),
      mov_b(Ref(Rcx), Rdx),
      mov_q(Rax, Rsi),
      Lbl(write_start),
      mov_d(Rbx, 10),
      Custom(CQO),
      IDivR(Rbx),
      AddRId(Rdx, b'0' as u32),
      DecR(Rcx),
      mov_b(Ref(Rcx), Rdx),
      LogicRR(Test, Rax, Rax),
      JCc(Ne, write_start),
      mov_b(Rax, is_neg),
      LogicRbRb(Test, Rax, Rax),
      JCc(E, write_positive),
      mov_b(Rdx, b'-'),
      DecR(Rcx),
      mov_b(Ref(Rcx), Rdx),
      Lbl(write_positive),
      mov_q(Rax, Rcx),
      Lbl(epilogue),
      mov_q(Rsi, tmp_s),
      mov_q(Rbx, tmp_b),
    ];
    self.link_function(id, insts, SIZE);
    Ok(id)
  }
  #[expect(clippy::too_many_lines)]
  pub(crate) fn get_utf8_slice(&mut self, caller: LabelId) -> ErrOR<LabelId> {
    const SIZE: i32 = 0x50;
    let id = symbol!(self, caller, UTF8_SLICE);
    let tmp_d = Local(Tmp, -0x08);
    let tmp_s = Local(Tmp, -0x10);
    let tmp_b = Local(Tmp, -0x18);
    let slice = Local(Tmp, -0x20);
    let slice_len = Local(Tmp, -0x28);
    let tmp_12 = Local(Tmp, -0x30);
    let start = self.id();
    let count = self.id();
    let done = self.id();
    let abort = self.id();
    let abort_count = self.id();
    let epilogue = self.id();
    let start_is_posi = self.id();
    let end_is_posi = self.id();
    let search_slice = self.id();
    let insts = &[
      mov_q(tmp_b, Rbx),
      mov_q(tmp_12, R12),
      mov_q(tmp_d, Rdx),
      mov_q(tmp_s, R8),
      mov_q(slice, Rcx),
      Clear(Rdx),
      Clear(R8),
      DecR(R8),
      Call(search_slice),
      mov_q(Rdx, tmp_d),
      mov_q(R8, tmp_s),
      mov_q(tmp_d, Rdi),
      mov_q(tmp_s, Rsi),
      Clear(Rcx),
      LogicRR(Cmp, Rdx, Rcx),
      JCc(Ge, start_is_posi),
      AddRR(Rdx, R11),
      Lbl(start_is_posi),
      LogicRR(Cmp, R8, Rcx),
      JCc(Ge, end_is_posi),
      AddRR(R8, R11),
      Lbl(end_is_posi),
      LogicRR(Cmp, Rdx, R8),
      JCc(Ge, abort),
      mov_q(Rcx, slice),
      Call(search_slice),
      LogicRbRb(Test, Rax, Rax),
      JCc(E, abort),
      mov_q(Rax, slice),
      AddRR(Rax, R9),
      mov_q(slice, Rax),
      mov_q(Rcx, Global(self.symbols[HEAP])),
      mov_d(Rdx, 8),
      mov_q(R8, R10),
      SubRR(R8, R9),
      mov_q(slice_len, R8),
      IncR(R8),
      CallApi(self.api(KERNEL32, "HeapAlloc")),
      IncMd(Global(self.symbols[LEAK_CNT])),
      mov_q(Rcx, slice_len),
      mov_q(Rdi, Rax),
      mov_q(Rsi, slice),
      Custom(CLD_REP_MOVSB),
      Jmp(epilogue),
      Lbl(abort),
      mov_q(Rcx, Global(self.symbols[HEAP])),
      mov_d(Rdx, 8),
      mov_d(R8, 1),
      CallApi(self.api(KERNEL32, "HeapAlloc")),
      IncMd(Global(self.symbols[LEAK_CNT])),
      Lbl(epilogue),
      mov_q(Rdi, tmp_d),
      mov_q(Rsi, tmp_s),
      mov_q(Rbx, tmp_b),
      mov_q(R12, tmp_12),
    ];
    self.link_function(id, insts, SIZE);
    self.use_function(id, search_slice);
    self.link_function(
      search_slice,
      &[
        Clear(Rax),
        Clear(R9),
        Clear(R10),
        Clear(R11),
        Lbl(start),
        mov_b(R12, SibDisp(Sib { base: Rcx, index: R10, scale: S1 }, Disp::Zero)),
        mov_b(Rax, R12),
        mov_b(Rbx, 0xC0),
        LogicRbRb(And, Rax, Rbx),
        mov_b(Rbx, 0x80),
        LogicRbRb(Cmp, Rax, Rbx),
        JCc(E, count),
        LogicRR(Cmp, R11, Rdx),
        CMovCc(E, R9, R10),
        LogicRR(Cmp, R11, R8),
        JCc(E, done),
        LogicRbRb(Test, R12, R12),
        JCc(E, abort_count),
        IncR(R11),
        Lbl(count),
        IncR(R10),
        Jmp(start),
        Lbl(done),
        Clear(Rax),
        IncR(Rax),
        Lbl(abort_count),
      ],
      SIZE,
    );
    Ok(id)
  }
  pub(crate) fn str_chars_len(&mut self, caller: LabelId) -> ErrOR<LabelId> {
    const SIZE: i32 = 0x30;
    let id = symbol!(self, caller, STR_CHARS_LEN);
    let start = self.id();
    let count = self.id();
    let epilogue = self.id();
    self.link_function(
      id,
      &[
        Clear(Rax),
        Clear(R9),
        Clear(R10),
        Clear(R11),
        Lbl(start),
        mov_b(R11, SibDisp(Sib { base: Rcx, index: R10, scale: S1 }, Disp::Zero)),
        LogicRbRb(Test, R11, R11),
        JCc(E, epilogue),
        mov_b(Rdx, 0xC0),
        LogicRbRb(And, R11, Rdx),
        mov_b(Rdx, 0x80),
        LogicRbRb(Cmp, R11, Rdx),
        JCc(E, count),
        IncR(Rax),
        Lbl(count),
        IncR(R10),
        Jmp(start),
        Lbl(epilogue),
      ],
      SIZE,
    );
    Ok(id)
  }
  pub(crate) fn str_eq(&mut self, caller: LabelId) -> ErrOR<LabelId> {
    const SIZE: i32 = 0x20;
    let id = symbol!(self, caller, STR_EQ);
    let epilogue = self.id();
    let case_true = self.id();
    let start = self.id();
    self.link_function(
      id,
      &[
        Clear(Rax),
        Lbl(start),
        mov_b(R8, Ref(Rcx)),
        mov_b(R9, Ref(Rdx)),
        LogicRbRb(Cmp, R8, R9),
        JCc(Ne, epilogue),
        LogicRbRb(Test, R8, R8),
        JCc(E, case_true),
        IncR(Rcx),
        IncR(Rdx),
        Jmp(start),
        Lbl(case_true),
        mov_b(Rax, 0xFF),
        Lbl(epilogue),
      ],
      SIZE,
    );
    Ok(id)
  }
  pub(crate) fn str_len(&mut self, caller: LabelId) -> ErrOR<LabelId> {
    const SIZE: i32 = 0x30;
    let id = symbol!(self, caller, STR_LEN);
    let tmp_d = Local(Tmp, -0x8);
    self.link_function(
      id,
      &[
        mov_q(tmp_d, Rdi),
        mov_q(Rdx, Rcx),
        mov_q(Rdi, Rdx),
        Clear(Rcx),
        DecR(Rcx),
        Clear(Rax),
        Custom(CLD_REPNE_SCASB),
        SubRR(Rdi, Rdx),
        DecR(Rdi),
        mov_q(Rax, Rdi),
        mov_q(Rdi, tmp_d),
      ],
      SIZE,
    );
    Ok(id)
  }
}