Skip to content

Commit

Permalink
Merge pull request #837 from goby-lang/fix-#584
Browse files Browse the repository at this point in the history
Fix #584
st0012 authored Mar 22, 2020

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
2 parents c21b38e + 9c2e449 commit c642dbc
Showing 2 changed files with 30 additions and 1 deletion.
13 changes: 12 additions & 1 deletion vm/thread.go
Original file line number Diff line number Diff line change
@@ -152,7 +152,18 @@ func (t *Thread) evalCallFrame(cf callFrame) {
t.Stack.Push(&Pointer{Target: result})
//fmt.Println(t.callFrameStack.inspect())
//fmt.Println("-----------------------")
t.callFrameStack.pop()

// this check is to prevent popping out a call frame that should be kept
// usually the top call frame would be the `cf` here
// but in some rare cases it could be other call frame, and if we pop it here we'll have some troubles in the later execution
//
// one example of the problem would be https://github.com/goby-lang/goby/issues/584
// the cause of this issue is that the "break" instruction always pops 3 call frames
// (this is necessary, please read the comments inside `Break` instruction for more detail)
// and because we already popped the `cf` during the `Break` instruction, what we pop here would be the top-level call frame, which causes the program to crash
if t.callFrameStack.top() == cf {
t.callFrameStack.pop()
}
}

t.removeUselessBlockFrame(cf)
18 changes: 18 additions & 0 deletions vm/vm_test.go
Original file line number Diff line number Diff line change
@@ -15,6 +15,24 @@ func TestVM_REPLExec(t *testing.T) {
inputs []string
expected interface{}
}{
{
[]string{
`
x = [1, 2, 3]
y = 0
`,
`
x.each do |i|
y += i
if i == 2
break
end
end
`,
`y`,
},
3,
},
{
[]string{
`

0 comments on commit c642dbc

Please sign in to comment.