From 1fb863e50169df9f97221f058281148aeab955a1 Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Sun, 8 Dec 2024 12:20:25 +0100 Subject: [PATCH] fix(gnovm): in op_binary, return typed booleans where appropriate --- gnovm/pkg/gnolang/op_binary.go | 35 +++++++++++++++++----------------- gnovm/tests/files/bool8.gno | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 gnovm/tests/files/bool8.gno diff --git a/gnovm/pkg/gnolang/op_binary.go b/gnovm/pkg/gnolang/op_binary.go index 6d26fa7ce54..3477fc61bdb 100644 --- a/gnovm/pkg/gnolang/op_binary.go +++ b/gnovm/pkg/gnolang/op_binary.go @@ -71,6 +71,17 @@ func (m *Machine) doOpLand() { lv.SetBool(lv.GetBool() && rv.GetBool()) } +// setMaybeUntypedBool sets lv to b; it will be untyped if both lv and rv are +// untyped; otherwise, it will be a typed bool. +func setMaybeUntypedBool(lv, rv *TypedValue, b bool) { + tp := BoolType + if isUntyped(lv.T) && isUntyped(rv.T) { + tp = UntypedBoolType + } + lv.T, lv.V = tp, nil + lv.SetBool(b) +} + func (m *Machine) doOpEql() { m.PopExpr() @@ -82,9 +93,7 @@ func (m *Machine) doOpEql() { } // set result in lv. res := isEql(m.Store, lv, rv) - lv.T = UntypedBoolType - lv.V = nil - lv.SetBool(res) + setMaybeUntypedBool(lv, rv, res) } func (m *Machine) doOpNeq() { @@ -99,9 +108,7 @@ func (m *Machine) doOpNeq() { // set result in lv. res := !isEql(m.Store, lv, rv) - lv.T = UntypedBoolType - lv.V = nil - lv.SetBool(res) + setMaybeUntypedBool(lv, rv, res) } func (m *Machine) doOpLss() { @@ -116,9 +123,7 @@ func (m *Machine) doOpLss() { // set the result in lv. res := isLss(lv, rv) - lv.T = UntypedBoolType - lv.V = nil - lv.SetBool(res) + setMaybeUntypedBool(lv, rv, res) } func (m *Machine) doOpLeq() { @@ -133,9 +138,7 @@ func (m *Machine) doOpLeq() { // set the result in lv. res := isLeq(lv, rv) - lv.T = UntypedBoolType - lv.V = nil - lv.SetBool(res) + setMaybeUntypedBool(lv, rv, res) } func (m *Machine) doOpGtr() { @@ -150,9 +153,7 @@ func (m *Machine) doOpGtr() { // set the result in lv. res := isGtr(lv, rv) - lv.T = UntypedBoolType - lv.V = nil - lv.SetBool(res) + setMaybeUntypedBool(lv, rv, res) } func (m *Machine) doOpGeq() { @@ -167,9 +168,7 @@ func (m *Machine) doOpGeq() { // set the result in lv. res := isGeq(lv, rv) - lv.T = UntypedBoolType - lv.V = nil - lv.SetBool(res) + setMaybeUntypedBool(lv, rv, res) } func (m *Machine) doOpAdd() { diff --git a/gnovm/tests/files/bool8.gno b/gnovm/tests/files/bool8.gno new file mode 100644 index 00000000000..9efbbbe6da2 --- /dev/null +++ b/gnovm/tests/files/bool8.gno @@ -0,0 +1,17 @@ +package main + +// results from comparisons should not be untyped bools + +var a interface{} = true + +func main() { + buf := "hello=" + isEqual(a, (buf[len(buf)-1] == '=')) +} + +func isEqual(v1, v2 interface{}) { + println("v1 == v2", v1 == v2) +} + +// Output: +// v1 == v2 true