package vm import ( "jinx/pkg/lang/vm/mem" "jinx/pkg/lang/vm/value" ) func (vm *VM) popAndDrop() (value.Value, error) { v, err := vm.stack.Pop() if err != nil { return value.Value{}, err } v.Drop(vm.memory) return v, nil } func (vm *VM) popCallAndDrop() (int, error) { envPtr := vm.stack.CurrentCallEnv() vm.memory.Release(envPtr) for !vm.stack.ReachedBaseOfCall() { _, err := vm.popAndDrop() if err != nil { return 0, err } } return vm.stack.PopCall() } func (vm *VM) getMemCell(ptr mem.Ptr, kind mem.CellKind, allowNil bool) (mem.CellData, error) { if ptr.IsNull() { return nil, ErrNullPtrDereference{At: ptr} } if !vm.memory.Is(ptr, kind) { return nil, ErrUnexpectedMemCell{Ptr: ptr, Expected: mem.CellKindEnv, Got: vm.memory.Kind(ptr)} } cell, err := vm.memory.Get(ptr) if err != nil { return nil, err } if cell == nil { if allowNil { return nil, nil } return nil, ErrMemNilCell{Ptr: ptr} } ok := false switch kind { case mem.CellKindString: _, ok = cell.(value.StringCell) case mem.CellKindArray: _, ok = cell.(value.ArrayCell) case mem.CellKindEnv: _, ok = cell.(value.EnvCell) case mem.CellKindOutlet: _, ok = cell.(value.OutletCell) case mem.CellKindType: _, ok = cell.(value.TypeCell) case mem.CellKindObject: _, ok = cell.(value.ObjectCell) } if !ok { return nil, ErrCorruptedMemCell{Ptr: ptr} } return cell, nil }