jsonpiler 0.10.1

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 heap_alloc = self.import(KERNEL32, "HeapAlloc");
    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 leak = Global(self.symbols[LEAK_CNT]);
    self.link_function(
      id,
      &[
        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(heap_alloc),
        IncMd(leak),
        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),
      ],
      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 heap_alloc = self.import(KERNEL32, "HeapAlloc");
    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 leak = Global(self.symbols[LEAK_CNT]);
    let i64_min_str = Global(self.global_str(i64::MIN.to_string()));
    let copy_str = self.copy_str(id)?;
    self.link_function(
      id,
      &[
        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(heap_alloc),
        IncMd(leak),
        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, i32::from(b'0')),
        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),
      ],
      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 heap_alloc = self.import(KERNEL32, "HeapAlloc");
    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 leak = Global(self.symbols[LEAK_CNT]);
    let search_slice = self.id();
    self.link_function(
      id,
      &[
        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(heap_alloc),
        IncMd(leak),
        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(heap_alloc),
        IncMd(leak),
        Lbl(epilogue),
        mov_q(Rdi, tmp_d),
        mov_q(Rsi, tmp_s),
        mov_q(Rbx, tmp_b),
        mov_q(R12, tmp_12),
      ],
      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)
  }
}