From 0a7700112f82e634a957685bee0cbaa3458f4945 Mon Sep 17 00:00:00 2001 From: Mel Date: Sat, 28 May 2022 01:22:17 +0000 Subject: Harden VM Mem --- pkg/lang/vm/utils.go | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 pkg/lang/vm/utils.go (limited to 'pkg/lang/vm/utils.go') diff --git a/pkg/lang/vm/utils.go b/pkg/lang/vm/utils.go new file mode 100644 index 0000000..95c0298 --- /dev/null +++ b/pkg/lang/vm/utils.go @@ -0,0 +1,69 @@ +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, ErrEnvNotSet + } + + 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) + } + + if !ok { + return nil, ErrCorruptedMemCell{Ptr: ptr} + } + + return cell, nil +} -- cgit 1.4.1