diff options
| author | Mel <einebeere@gmail.com> | 2022-07-26 19:52:31 +0000 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2022-07-26 19:52:31 +0000 |
| commit | 7392283d9e6b8c1ee31a3ad74ce8d13d4e8b19ec (patch) | |
| tree | 434350324985297cd16dd1df68a417223a334332 | |
| parent | 20bd5570465c73b89458de58c9fb8cd4e5919b44 (diff) | |
| download | jinx-7392283d9e6b8c1ee31a3ad74ce8d13d4e8b19ec.tar.zst jinx-7392283d9e6b8c1ee31a3ad74ce8d13d4e8b19ec.zip | |
Fix cloning of outlets and don't drop nil cells
| -rw-r--r-- | pkg/lang/vm/mem/mem.go | 5 | ||||
| -rw-r--r-- | pkg/lang/vm/value/value.go | 5 | ||||
| -rw-r--r-- | pkg/lang/vm/vm_test.go | 39 |
3 files changed, 48 insertions, 1 deletions
diff --git a/pkg/lang/vm/mem/mem.go b/pkg/lang/vm/mem/mem.go index 6c1d58d..99412ea 100644 --- a/pkg/lang/vm/mem/mem.go +++ b/pkg/lang/vm/mem/mem.go @@ -142,7 +142,10 @@ func (m *memImpl) Release(ptr Ptr) error { m.cells[ptr].refs-- if m.cells[ptr].refs == 0 { c := m.cells[ptr].data - c.DropCell(m) + + if c != nil { + c.DropCell(m) + } m.cells[ptr] = cell{} m.free = append(m.free, ptr) diff --git a/pkg/lang/vm/value/value.go b/pkg/lang/vm/value/value.go index 953ac8b..5dd5012 100644 --- a/pkg/lang/vm/value/value.go +++ b/pkg/lang/vm/value/value.go @@ -155,6 +155,11 @@ func (v Value) Clone(m mem.Mem) Value { m.Retain(fn.env) } + // If value has an outlet don't copy it into the clone, + // otherwise when the clone is dropped it will also drop the outlet. + // I don't know if this fixes the entire problem, but it seems to work. + v.outlet = mem.NullPtr + return v } diff --git a/pkg/lang/vm/vm_test.go b/pkg/lang/vm/vm_test.go index 7e749a4..ae0b8e6 100644 --- a/pkg/lang/vm/vm_test.go +++ b/pkg/lang/vm/vm_test.go @@ -184,6 +184,45 @@ func TestEscapedEnv(t *testing.T) { test(t, src, "[1, 2, 3]") } +func TestEnvNotEscaped(t *testing.T) { + /* + var x = 1 + + fn f() { + x = x + 1 + return + } + + f() + var result = x + */ + + src := ` + push_int 1 + + push_function @f + add_to_env 0 + get_local 1 + + call 0 + drop 1 + + get_local 0 + halt + + @f: + get_env 0 + push_int 1 + add + set_env 0 + + push_null + ret + ` + + test(t, src, "2") +} + func TestMember(t *testing.T) { src := ` push_array |
