diff --git a/pkg/compiler/visitor.go b/pkg/compiler/visitor.go index 2dbbecab..7571638a 100644 --- a/pkg/compiler/visitor.go +++ b/pkg/compiler/visitor.go @@ -233,7 +233,7 @@ func (v *visitor) VisitForExpression(ctx *fql.ForExpressionContext) interface{} if isForInLoop { // pop the iterator - v.emitPop() + v.emitPopAndClose() } return nil @@ -918,6 +918,10 @@ func (v *visitor) emitPop() { v.emit(runtime.OpPop) } +func (v *visitor) emitPopAndClose() { + v.emit(runtime.OpPopClose) +} + func (v *visitor) emit(op runtime.Opcode, args ...int) { v.bytecode = append(v.bytecode, op) diff --git a/pkg/runtime/opcodes.go b/pkg/runtime/opcodes.go index 53c20ac2..638b6121 100644 --- a/pkg/runtime/opcodes.go +++ b/pkg/runtime/opcodes.go @@ -47,8 +47,9 @@ const ( OpCall3 OpCall4 OpCallN - OpPop OpPush + OpPop + OpPopClose OpJumpIfFalse OpJumpIfTrue OpJump diff --git a/pkg/runtime/vm.go b/pkg/runtime/vm.go index 202b5eeb..20360b83 100644 --- a/pkg/runtime/vm.go +++ b/pkg/runtime/vm.go @@ -7,6 +7,7 @@ import ( "github.com/MontFerret/ferret/pkg/runtime/operators" "github.com/MontFerret/ferret/pkg/runtime/values" "github.com/MontFerret/ferret/pkg/runtime/values/types" + "io" ) type VM struct { @@ -58,6 +59,13 @@ loop: case OpPop: stack.Pop() + case OpPopClose: + closable, ok := stack.Pop().(io.Closer) + + if ok { + closable.Close() + } + case OpStoreGlobal: vm.globals[program.Constants[arg].String()] = stack.Pop()