///|
fn Vm::object_value(self : Vm, layers : Array[Layer]) -> Value {
  let obj = {
    layers,
    cache: Map([]),
    scopes: Map([]),
    assertion_state: 0,
    assertion_error: None,
    standard: false,
  }
  let id = if self.free_objects.pop() is Some(id) {
    self.objects[id] = obj
    id
  } else {
    let id = self.objects.length()
    self.objects.push(obj)
    id
  }
  ObjectValue(id, layers.length())
}

///|
fn Vm::scope(self : Vm, id : Int, layer : Int, outer : Env) -> Env {
  let obj = self.objects[id]
  let env = outer
    .child()
    .trace_context("object <" + outer.diagnostic_context.1 + ">")
  env.names["self"] = self.store(Ready(ObjectValue(id, obj.layers.length())))
  env.names["super"] = self.store(Ready(ObjectValue(id, layer)))
  if obj.standard {
    env.names["$std"] = env.names["self"]
  }
  if env.lookup("$") is None {
    env.names["$"] = env.names["self"]
  }
  self.bind(obj.layers[layer].locals, env)
}

///|
fn Vm::layer_scope(self : Vm, id : Int, layer : Int) -> Env {
  let obj = self.objects[id]
  match obj.scopes.get(layer) {
    Some(e) => e
    None => {
      let e = self.scope(id, layer, obj.layers[layer].env)
      obj.scopes[layer] = e
      e
    }
  }
}

///|
fn Vm::check_assertions(self : Vm, id : Int, loc : Location) -> Unit raise {
  let obj = self.objects[id]
  if obj.assertion_error is Some(error) {
    raise copy_evaluation_error(error)
  }
  if obj.assertion_state != 0 {
    return
  }
  obj.assertion_state = 1
  errdefer {
    obj.assertion_state = 0
  }
  try {
    for i in 0.. site)
              .unwrap_or({
                begin: cond.loc,
                end: diagnostic_expr_end(msg.unwrap_or(cond)),
              }),
            ),
            name: "",
          },
        )
      }
    }
  } catch {
    e => {
      if self.persistent {
        obj.assertion_error = Some(copy_evaluation_error(e))
      }
      raise copy_evaluation_error(e)
    }
  }
  obj.assertion_state = 2
  self.tick(loc)
}

///|
fn Vm::has_field(self : Vm, id : Int, top : Int, name : String) -> Bool {
  for i in 0.. Bool {
  let mut visible = true
  for i in 0..