jsonpiler 0.11.0

a Json syntax programming language for Windows
Documentation
use crate::prelude::*;
impl Jsonpiler {
  pub(crate) fn call_alloc_r8_x(&mut self) -> ErrOR<Vec<X64Inst>> {
    let leak = Global(self.get_leak()?);
    let heap = Global(self.get_heap()?);
    Ok(vec![
      load(S8, Rcx, heap),
      MovMId(Reg(Rdx), 8),
      CallApiCheck(self.api(KERNEL32, "HeapAlloc")),
      IncMd(leak),
    ])
  }
  pub(crate) fn call_alloc_x0_a(&mut self) -> ErrOR<Vec<A64Inst>> {
    let leak = Global(self.get_leak()?).v_rd();
    let alloc = self.api(SYS_B, "_malloc");
    let mut insts = vec![BApi(alloc)];
    insts.extend_from_slice(&inc_a(leak, X1, X2)?);
    Ok(insts)
  }
  pub(crate) fn call_api_minus_one_a(
    &mut self,
    dylib: &'static str,
    api: &'static str,
  ) -> Vec<A64Inst> {
    vec![
      BApi(self.api(dylib, api)),
      AddRI12(X0, X0, 1),
      CmpRR(X0, Xzr),
      BCc(E.into(), self.handlers.os),
      SubRI12(X0, X0, 1),
    ]
  }
  pub(crate) fn call_api_zero_a(&mut self, dylib: &'static str, api: &'static str) -> Vec<A64Inst> {
    vec![BApi(self.api(dylib, api)), CmpRR(X0, Xzr), BCc(E.into(), self.handlers.os)]
  }
  pub(crate) fn call_free_r8_x(&mut self) -> ErrOR<Vec<X64Inst>> {
    let leak = Global(self.get_leak()?);
    let heap = Global(self.get_heap()?);
    Ok(vec![
      load(S8, Rcx, heap),
      Clear(Rdx),
      CallApiCheck(self.api(KERNEL32, "HeapFree")),
      DecMd(leak),
    ])
  }
  pub(crate) fn call_free_x0_a(&mut self) -> ErrOR<Vec<A64Inst>> {
    let leak = Global(self.get_leak()?).v_rd();
    let free = self.api(SYS_B, "_free");
    let mut insts = vec![BApi(free)];
    insts.extend_from_slice(&load_a(X0, leak)?);
    insts.push(SubRI12(X0, X0, 1));
    insts.extend_from_slice(&store_a(leak, X1, X0)?);
    Ok(insts)
  }
  pub(crate) fn drop_all(&mut self, result: Json, scope: &mut Scope) -> ErrOR<()> {
    self.drop_json(&result, false, scope)?;
    self.drop_all_local(scope)?;
    self.drop_global(scope)
  }
  pub(crate) fn drop_all_local(&mut self, scope: &mut Scope) -> ErrOR<()> {
    for _ in 0..scope.locals.len() {
      self.drop_scope(scope)?;
    }
    self.drop_var_table(
      take(&mut scope.local_top),
      |jsonpiler, json, scope_2| jsonpiler.drop_json(json, true, scope_2),
      scope,
    )
  }
  fn drop_global(&mut self, scope: &mut Scope) -> ErrOR<()> {
    let globals = take(&mut self.globals);
    self.drop_var_table(
      globals,
      |jsonpiler, json, scope_2| {
        if let Some(mem) = json.mem() { jsonpiler.heap_free(mem, scope_2) } else { Ok(()) }
      },
      scope,
    )
  }
  pub(crate) fn drop_json(&mut self, json: &Json, force: bool, scope: &mut Scope) -> ErrOR<()> {
    if let Some(mem @ Memory(Local(lifetime, offset), mem_type)) = json.mem()
      && (force || lifetime == Tmp)
    {
      scope.free(offset, mem_type.size()?)?;
      self.heap_free(mem, scope)?;
    }
    Ok(())
  }
  pub(crate) fn drop_scope(&mut self, scope: &mut Scope) -> ErrOR<()> {
    self.drop_var_table(
      scope.locals.pop().unwrap_or_default(),
      |jsonpiler, json, scope_2| jsonpiler.drop_json(json, true, scope_2),
      scope,
    )
  }
  fn drop_var_table<F>(
    &mut self,
    var_table: BTreeMap<String, Pos<Variable>>,
    mut free: F,
    scope: &mut Scope,
  ) -> ErrOR<()>
  where
    F: FnMut(&mut Jsonpiler, &Json, &mut Scope) -> ErrOR<()>,
  {
    for (name, variable) in var_table {
      if variable.val.refs.is_empty() && !name.starts_with('_') {
        self.warn(variable.pos.with(UnusedName(variable.val.kind, name.clone())))?;
      }
      self.push_sym(SymbolInfo {
        def: Some(variable.pos),
        name,
        kind: variable.val.kind,
        json_type: variable.val.val.as_type(),
        refs: variable.val.refs,
      });
      free(self, &variable.val.val, scope)?;
    }
    Ok(())
  }
  pub(crate) fn heap_free(&mut self, mem: Memory, scope: &mut Scope) -> ErrOR<()> {
    if mem.1.pass_by == HeapPtr {
      if self.flags.a64 {
        scope.e_a(self.heap_free_a(mem)?)?;
      } else {
        scope.e_x(self.heap_free_x(mem)?)?;
      }
    }
    Ok(())
  }
  pub(crate) fn heap_free_a(&mut self, mem: Memory) -> ErrOR<Vec<A64Inst>> {
    Ok(if mem.1.pass_by == HeapPtr {
      [load_a(X0, mem)?, self.call_free_x0_a()?].concat()
    } else {
      vec![]
    })
  }
  pub(crate) fn heap_free_x(&mut self, mem: Memory) -> ErrOR<Vec<X64Inst>> {
    Ok(if mem.1.pass_by == HeapPtr {
      [vec![load(S8, R8, mem.0)], self.call_free_r8_x()?].concat()
    } else {
      vec![]
    })
  }
}