vm: make Iterator interface public

There is nothing wrong with iterators being implemented in other parts
of code (e.g. Storage.Find). In this case type assertions can
prevent bugs at compile-time.
This commit is contained in:
Evgenii Stratonikov 2020-05-27 11:09:23 +03:00
parent 503442a60d
commit b0d07c3031
3 changed files with 16 additions and 13 deletions

View file

@ -11,6 +11,8 @@ type storageWrapper struct {
finished bool finished bool
} }
var _ vm.Iterator = (*storageWrapper)(nil)
// newStorageIterator returns new storage iterator from the `next()` callback. // newStorageIterator returns new storage iterator from the `next()` callback.
func newStorageIterator(next dao.StorageIteratorFunc) *storageWrapper { func newStorageIterator(next dao.StorageIteratorFunc) *storageWrapper {
return &storageWrapper{ return &storageWrapper{
@ -18,7 +20,7 @@ func newStorageIterator(next dao.StorageIteratorFunc) *storageWrapper {
} }
} }
// Next implements iterator interface. // Next implements vm.Iterator interface.
func (s *storageWrapper) Next() bool { func (s *storageWrapper) Next() bool {
if s.finished { if s.finished {
return false return false
@ -33,12 +35,12 @@ func (s *storageWrapper) Next() bool {
return true return true
} }
// Value implements iterator interface. // Value implements vm.Iterator interface.
func (s *storageWrapper) Value() vm.StackItem { func (s *storageWrapper) Value() vm.StackItem {
return s.value return s.value
} }
// Key implements iterator interface. // Key implements vm.Iterator interface.
func (s *storageWrapper) Key() vm.StackItem { func (s *storageWrapper) Key() vm.StackItem {
return s.key return s.key
} }

View file

@ -205,9 +205,9 @@ func NewMapIterator(m *MapItem) *InteropItem {
// IteratorConcat handles syscall Neo.Iterator.Concat. // IteratorConcat handles syscall Neo.Iterator.Concat.
func IteratorConcat(v *VM) error { func IteratorConcat(v *VM) error {
iop1 := v.Estack().Pop().Interop() iop1 := v.Estack().Pop().Interop()
iter1 := iop1.value.(iterator) iter1 := iop1.value.(Iterator)
iop2 := v.Estack().Pop().Interop() iop2 := v.Estack().Pop().Interop()
iter2 := iop2.value.(iterator) iter2 := iop2.value.(Iterator)
v.Estack().Push(&Element{value: NewInteropItem( v.Estack().Push(&Element{value: NewInteropItem(
&concatIter{ &concatIter{
@ -222,7 +222,7 @@ func IteratorConcat(v *VM) error {
// IteratorKey handles syscall Neo.Iterator.Key. // IteratorKey handles syscall Neo.Iterator.Key.
func IteratorKey(v *VM) error { func IteratorKey(v *VM) error {
iop := v.estack.Pop().Interop() iop := v.estack.Pop().Interop()
iter := iop.value.(iterator) iter := iop.value.(Iterator)
v.Estack().Push(&Element{value: iter.Key()}) v.Estack().Push(&Element{value: iter.Key()})
return nil return nil
@ -231,7 +231,7 @@ func IteratorKey(v *VM) error {
// IteratorKeys handles syscall Neo.Iterator.Keys. // IteratorKeys handles syscall Neo.Iterator.Keys.
func IteratorKeys(v *VM) error { func IteratorKeys(v *VM) error {
iop := v.estack.Pop().Interop() iop := v.estack.Pop().Interop()
iter := iop.value.(iterator) iter := iop.value.(Iterator)
v.Estack().Push(&Element{value: NewInteropItem( v.Estack().Push(&Element{value: NewInteropItem(
&keysWrapper{iter}, &keysWrapper{iter},
)}) )})
@ -242,7 +242,7 @@ func IteratorKeys(v *VM) error {
// IteratorValues handles syscall Neo.Iterator.Values. // IteratorValues handles syscall Neo.Iterator.Values.
func IteratorValues(v *VM) error { func IteratorValues(v *VM) error {
iop := v.estack.Pop().Interop() iop := v.estack.Pop().Interop()
iter := iop.value.(iterator) iter := iop.value.(Iterator)
v.Estack().Push(&Element{value: NewInteropItem( v.Estack().Push(&Element{value: NewInteropItem(
&valuesWrapper{iter}, &valuesWrapper{iter},
)}) )})

View file

@ -18,7 +18,8 @@ type (
) )
type ( type (
iterator interface { // Iterator defined public interface for VM's iterator type.
Iterator interface {
enumerator enumerator
Key() StackItem Key() StackItem
} }
@ -29,16 +30,16 @@ type (
} }
concatIter struct { concatIter struct {
current iterator current Iterator
second iterator second Iterator
} }
keysWrapper struct { keysWrapper struct {
iter iterator iter Iterator
} }
valuesWrapper struct { valuesWrapper struct {
iter iterator iter Iterator
} }
) )