aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2022-08-29 20:30:10 +0000
committerMel <einebeere@gmail.com>2022-08-29 20:40:44 +0000
commit1bc5eb0d13bb001b4ac7f456c6a61fedcd53f0c8 (patch)
tree336f8eb7e3e49cf647eec3abc4be18412bc0f684
parent1f5a49151fc2f72932eedf8162b63af670556910 (diff)
downloadjinx-1bc5eb0d13bb001b4ac7f456c6a61fedcd53f0c8.tar.zst
jinx-1bc5eb0d13bb001b4ac7f456c6a61fedcd53f0c8.zip
Stop ignoring val.Drop and val.Clone memory errors
-rw-r--r--pkg/lang/vm/exec.go91
-rw-r--r--pkg/lang/vm/mem/cell.go2
-rw-r--r--pkg/lang/vm/mem/mem.go4
-rw-r--r--pkg/lang/vm/mem/mem_test.go2
-rw-r--r--pkg/lang/vm/utils.go4
-rw-r--r--pkg/lang/vm/value/cells.go48
-rw-r--r--pkg/lang/vm/value/value.go35
7 files changed, 138 insertions, 48 deletions
diff --git a/pkg/lang/vm/exec.go b/pkg/lang/vm/exec.go
index a64751a..8cdcdcc 100644
--- a/pkg/lang/vm/exec.go
+++ b/pkg/lang/vm/exec.go
@@ -120,7 +120,11 @@ func (vm *VM) execGetGlobal(name string) error {
return ErrNoSuchGlobal{GlobalName: name}
}
- v = v.Clone(vm.memory)
+ v, err = v.Clone(vm.memory)
+ if err != nil {
+ return err
+ }
+
vm.stack.Push(v)
return nil
}
@@ -150,7 +154,10 @@ func (vm *VM) execGetLocal(offset int) error {
return err
}
- v := local.Clone(vm.memory)
+ v, err := local.Clone(vm.memory)
+ if err != nil {
+ return err
+ }
vm.stack.Push(v)
return nil
@@ -167,7 +174,9 @@ func (vm *VM) execSetLocal(offset int) error {
return err
}
- local.Drop(vm.memory)
+ if err := local.Drop(vm.memory); err != nil {
+ return err
+ }
stackIndex := vm.stack.LocalToStackIndex(offset)
return vm.stack.Set(stackIndex, new)
@@ -211,10 +220,17 @@ func (vm *VM) execGetMember(name string) error {
objCell := cell.(value.ObjectCell)
member, ok := objCell.Get()[name]
if ok {
- member = member.Clone(vm.memory)
+ member, err = member.Clone(vm.memory)
+ if err != nil {
+ return err
+ }
vm.stack.Push(member)
- parent.Drop(vm.memory)
+
+ if err := parent.Drop(vm.memory); err != nil {
+ return err
+ }
+
return nil
}
}
@@ -250,7 +266,11 @@ func (vm *VM) execGetMember(name string) error {
// method = method.Clone(vm.memory) will only be necessary when we support methods with environments.
vm.stack.Push(method)
- parent.Drop(vm.memory)
+
+ if err := parent.Drop(vm.memory); err != nil {
+ return err
+ }
+
return nil
}
}
@@ -303,7 +323,9 @@ func (vm *VM) execGetMember(name string) error {
val := value.NewFunction(code.Pos{}, 0).WithData(member)
vm.stack.Push(val)
- parent.Drop(vm.memory)
+ if err := parent.Drop(vm.memory); err != nil {
+ return err
+ }
return nil
}
@@ -342,7 +364,9 @@ func (vm *VM) execSetMember(name string) error {
return err
}
- parent.Drop(vm.memory)
+ if err := parent.Drop(vm.memory); err != nil {
+ return err
+ }
// v was moved, no need to drop it.
return nil
@@ -365,7 +389,11 @@ func (vm *VM) execGetEnv(envIndex int) error {
if outletCell != nil {
// Outlet is not null, so value escaped.
outlet := outletCell.(value.OutletCell).Get()
- val := outlet.Clone(vm.memory)
+ val, err := outlet.Clone(vm.memory)
+ if err != nil {
+ return err
+ }
+
vm.stack.Push(val)
return nil
}
@@ -377,7 +405,11 @@ func (vm *VM) execGetEnv(envIndex int) error {
return err
}
- val = val.Clone(vm.memory)
+ val, err = val.Clone(vm.memory)
+ if err != nil {
+ return err
+ }
+
vm.stack.Push(val)
return nil
@@ -404,7 +436,10 @@ func (vm *VM) execSetEnv(envIndex int) error {
if outletCell != nil {
// Outlet is not null, so value escaped.
outlet := outletCell.(value.OutletCell).Get()
- outlet.Drop(vm.memory)
+ if err := outlet.Drop(vm.memory); err != nil {
+ return err
+ }
+
vm.memory.Set(outletPtr, value.OutletCell(new))
return nil
}
@@ -415,7 +450,9 @@ func (vm *VM) execSetEnv(envIndex int) error {
return err
}
- old.Drop(vm.memory)
+ if err := old.Drop(vm.memory); err != nil {
+ return err
+ }
return vm.stack.Set(stackIndex, new)
}
@@ -583,8 +620,13 @@ func (vm *VM) execGenericBinaryOperation(op code.Op, fns typesToBinaryOperation)
return err
}
- x.Drop(vm.memory)
- y.Drop(vm.memory)
+ if err := x.Drop(vm.memory); err != nil {
+ return err
+ }
+
+ if err := y.Drop(vm.memory); err != nil {
+ return err
+ }
vm.stack.Push(res)
return nil
@@ -735,8 +777,13 @@ func (vm *VM) execEq() error {
}
result := func(res bool) error {
- x.Drop(vm.memory)
- y.Drop(vm.memory)
+ if err := x.Drop(vm.memory); err != nil {
+ return err
+ }
+
+ if err := y.Drop(vm.memory); err != nil {
+ return err
+ }
vm.stack.Push(value.NewBool(res))
return nil
@@ -812,7 +859,12 @@ func (vm *VM) execIndex() error {
if err != nil {
return err
}
- val = val.Clone(vm.memory)
+
+ val, err = val.Clone(vm.memory)
+ if err != nil {
+ return err
+ }
+
vm.stack.Push(val)
default:
return ErrInvalidOperandTypes{
@@ -1027,7 +1079,10 @@ func (vm *VM) execTempArrLen() error {
}
res := value.NewInt(int64(len))
vm.stack.Push(res)
- a.Drop(vm.memory)
+
+ if err := a.Drop(vm.memory); err != nil {
+ return err
+ }
default:
return ErrInvalidOperandTypes{
Op: code.OpTempArrLen,
diff --git a/pkg/lang/vm/mem/cell.go b/pkg/lang/vm/mem/cell.go
index 85d6c34..0a5e80c 100644
--- a/pkg/lang/vm/mem/cell.go
+++ b/pkg/lang/vm/mem/cell.go
@@ -49,6 +49,6 @@ type cell struct {
}
type CellData interface {
- DropCell(Mem)
+ DropCell(Mem) error
MatchingCellKind() CellKind
}
diff --git a/pkg/lang/vm/mem/mem.go b/pkg/lang/vm/mem/mem.go
index 99412ea..b590bcc 100644
--- a/pkg/lang/vm/mem/mem.go
+++ b/pkg/lang/vm/mem/mem.go
@@ -144,7 +144,9 @@ func (m *memImpl) Release(ptr Ptr) error {
c := m.cells[ptr].data
if c != nil {
- c.DropCell(m)
+ if err := c.DropCell(m); err != nil {
+ return err
+ }
}
m.cells[ptr] = cell{}
diff --git a/pkg/lang/vm/mem/mem_test.go b/pkg/lang/vm/mem/mem_test.go
index f916e49..0c74093 100644
--- a/pkg/lang/vm/mem/mem_test.go
+++ b/pkg/lang/vm/mem/mem_test.go
@@ -208,7 +208,7 @@ func TestChainDrop(t *testing.T) {
assert.Equal(t, mem.CellKindArray, m.Kind(mem.Ptr(5)))
assert.Equal(t, mem.CellKindEmpty, m.Kind(mem.Ptr(6)))
- val.Drop(m)
+ assert.NoError(t, val.Drop(m))
for _, ptr := range []mem.Ptr{1, 2, 3, 4, 5, 6} {
assert.Equal(t, mem.CellKindEmpty, m.Kind(ptr))
diff --git a/pkg/lang/vm/utils.go b/pkg/lang/vm/utils.go
index 975d31b..eddcc11 100644
--- a/pkg/lang/vm/utils.go
+++ b/pkg/lang/vm/utils.go
@@ -12,7 +12,9 @@ func (vm *VM) popAndDrop() (value.Value, error) {
if err != nil {
return value.Value{}, err
}
- v.Drop(vm.memory)
+ if err := v.Drop(vm.memory); err != nil {
+ return value.Value{}, err
+ }
return v, nil
}
diff --git a/pkg/lang/vm/value/cells.go b/pkg/lang/vm/value/cells.go
index 19ecfde..646f3c1 100644
--- a/pkg/lang/vm/value/cells.go
+++ b/pkg/lang/vm/value/cells.go
@@ -1,16 +1,21 @@
package value
import (
+ "fmt"
"jinx/pkg/lang/vm/code"
"jinx/pkg/lang/vm/mem"
)
type ArrayCell []Value
-func (a ArrayCell) DropCell(m mem.Mem) {
+func (a ArrayCell) DropCell(m mem.Mem) error {
for _, v := range a {
- v.Drop(m)
+ if err := v.Drop(m); err != nil {
+ return err
+ }
}
+
+ return nil
}
func (a ArrayCell) MatchingCellKind() mem.CellKind {
@@ -23,7 +28,8 @@ func (a ArrayCell) Get() []Value {
type StringCell string
-func (s StringCell) DropCell(m mem.Mem) {
+func (s StringCell) DropCell(m mem.Mem) error {
+ return nil
}
func (s StringCell) MatchingCellKind() mem.CellKind {
@@ -38,10 +44,14 @@ type ObjectCell struct {
Members map[string]Value
}
-func (o ObjectCell) DropCell(m mem.Mem) {
+func (o ObjectCell) DropCell(m mem.Mem) error {
for _, v := range o.Members {
- v.Drop(m)
+ if err := v.Drop(m); err != nil {
+ return err
+ }
}
+
+ return nil
}
func (o ObjectCell) MatchingCellKind() mem.CellKind {
@@ -54,17 +64,23 @@ func (o ObjectCell) Get() map[string]Value {
type TypeCell Type
-func (t TypeCell) DropCell(m mem.Mem) {
+func (t TypeCell) DropCell(m mem.Mem) error {
typ := t.Get()
for _, f := range typ.Methods {
// Wrap data in a Value to drop it.
val := NewFunction(code.Pos{}, 0).WithData(f)
- val.Drop(m)
+ if err := val.Drop(m); err != nil {
+ return err
+ }
}
for _, v := range typ.Statics {
- v.Drop(m)
+ if err := v.Drop(m); err != nil {
+ return err
+ }
}
+
+ return nil
}
func (t TypeCell) MatchingCellKind() mem.CellKind {
@@ -77,8 +93,8 @@ func (t TypeCell) Get() Type {
type OutletCell Value
-func (o OutletCell) DropCell(m mem.Mem) {
- Value(o).Drop(m)
+func (o OutletCell) DropCell(m mem.Mem) error {
+ return Value(o).Drop(m)
}
func (o OutletCell) MatchingCellKind() mem.CellKind {
@@ -91,10 +107,14 @@ func (o OutletCell) Get() Value {
type EnvCell Env
-func (e EnvCell) DropCell(m mem.Mem) {
+func (e EnvCell) DropCell(m mem.Mem) error {
for _, v := range e.references {
- m.Release(v.outlet)
+ if err := m.Release(v.outlet); err != nil {
+ return err
+ }
}
+
+ return nil
}
func (e EnvCell) MatchingCellKind() mem.CellKind {
@@ -107,8 +127,8 @@ func (e EnvCell) Get() Env {
type GlobalCell Value
-func (g GlobalCell) DropCell(m mem.Mem) {
- panic("global cell cannot be dropped")
+func (g GlobalCell) DropCell(m mem.Mem) error {
+ return fmt.Errorf("global cell cannot be dropped")
}
func (g GlobalCell) MatchingCellKind() mem.CellKind {
diff --git a/pkg/lang/vm/value/value.go b/pkg/lang/vm/value/value.go
index cce2f5e..e2750f4 100644
--- a/pkg/lang/vm/value/value.go
+++ b/pkg/lang/vm/value/value.go
@@ -142,20 +142,28 @@ func (v Value) IsEmpty() bool {
return v == Value{}
}
-func (v Value) Clone(m mem.Mem) Value {
+func (v Value) Clone(m mem.Mem) (Value, error) {
if v.t == StringType {
str := v.d.(StringData)
- m.Retain(str.data)
+ if err := m.Retain(str.data); err != nil {
+ return Value{}, err
+ }
}
if v.t == ArrayType {
arr := v.d.(ArrayData)
- m.Retain(arr.data)
+ if err := m.Retain(arr.data); err != nil {
+ return Value{}, err
+ }
}
if v.t == FunctionType {
fn := v.d.(FunctionData)
- m.Retain(fn.env)
+ if !fn.env.IsNull() {
+ if err := m.Retain(fn.env); err != nil {
+ return Value{}, err
+ }
+ }
}
// If value has an outlet don't copy it into the clone,
@@ -163,28 +171,31 @@ func (v Value) Clone(m mem.Mem) Value {
// I don't know if this fixes the entire problem, but it seems to work.
v.outlet = mem.NullPtr
- return v
+ return v, nil
}
-func (v Value) Drop(m mem.Mem) {
+func (v Value) Drop(m mem.Mem) error {
// If value has an outlet, don't drop it and instead move it to the outlet.
if !v.outlet.IsNull() {
- m.Set(v.outlet, OutletCell(v))
- return
+ return m.Set(v.outlet, OutletCell(v))
}
if v.t == StringType {
str := v.d.(StringData)
- m.Release(str.data)
+ return m.Release(str.data)
}
if v.t == ArrayType {
arr := v.d.(ArrayData)
- m.Release(arr.data)
+ return m.Release(arr.data)
}
if v.t == FunctionType {
- f := v.d.(FunctionData)
- m.Release(f.env)
+ fn := v.d.(FunctionData)
+ if !fn.env.IsNull() {
+ return m.Release(fn.env)
+ }
}
+
+ return nil
}