Skip to content

Commit

Permalink
feat: refactor again
Browse files Browse the repository at this point in the history
  • Loading branch information
omarsy committed Dec 1, 2024
1 parent 853a9d3 commit 8b46e01
Show file tree
Hide file tree
Showing 14 changed files with 575 additions and 334 deletions.
6 changes: 2 additions & 4 deletions gno.land/pkg/sdk/vm/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ package vm
import (
"encoding/base64"
"fmt"
"math"
"strconv"
"strings"

"github.com/cockroachdb/apd/v3"
gno "github.com/gnolang/gno/gnovm/pkg/gnolang"
"github.com/gnolang/gno/gnovm/pkg/gnolang/softfloat"
)

func assertNoPlusPrefix(s string) {
Expand Down Expand Up @@ -145,11 +143,11 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) {
return
case gno.Float32Type:
value := convertFloat(arg, 32)
tv.SetFloat32(softfloat.Float32(math.Float32bits(float32(value))))
tv.SetFloat32(gno.ConvertToSoftFloat32(value))
return
case gno.Float64Type:
value := convertFloat(arg, 64)
tv.SetFloat64(softfloat.Float64(math.Float64bits(value)))
tv.SetFloat64(gno.ConvertToSoftFloat64(value))
return
default:
panic(fmt.Sprintf("unexpected primitive type %s", bt.String()))
Expand Down
19 changes: 8 additions & 11 deletions gnovm/pkg/gnolang/gonative.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ package gnolang

import (
"fmt"
"math"
"reflect"

"github.com/gnolang/gno/gnovm/pkg/gnolang/softfloat"
)

// NOTE
Expand Down Expand Up @@ -332,9 +329,9 @@ func go2GnoValue(alloc *Allocator, rv reflect.Value) (tv TypedValue) {
case reflect.Uint64:
tv.SetUint64(rv.Uint())
case reflect.Float32:
tv.SetFloat32(softfloat.Float32(math.Float32bits(float32(rv.Float()))))
tv.SetFloat32(ConvertToSoftFloat32(rv.Float()))
case reflect.Float64:
tv.SetFloat64(softfloat.Float64(math.Float64bits(rv.Float())))
tv.SetFloat64(ConvertToSoftFloat64(rv.Float()))
case reflect.Array:
tv.V = alloc.NewNative(rv)
case reflect.Slice:
Expand Down Expand Up @@ -431,11 +428,11 @@ func go2GnoValueUpdate(alloc *Allocator, rlm *Realm, lvl int, tv *TypedValue, rv
}
case Float32Kind:
if lvl != 0 {
tv.SetFloat32(softfloat.Float32(math.Float32bits(float32(rv.Float()))))
tv.SetFloat32(ConvertToSoftFloat32(rv.Float()))
}
case Float64Kind:
if lvl != 0 {
tv.SetFloat64(softfloat.Float64(math.Float64bits(rv.Float())))
tv.SetFloat64(ConvertToSoftFloat64(rv.Float()))
}
case BigintKind:
panic("not yet implemented")
Expand Down Expand Up @@ -647,9 +644,9 @@ func go2GnoValue2(alloc *Allocator, store Store, rv reflect.Value, recursive boo
case reflect.Uint64:
tv.SetUint64(rv.Uint())
case reflect.Float32:
tv.SetFloat32(softfloat.Float32(math.Float32bits(float32(rv.Float()))))
tv.SetFloat32(ConvertToSoftFloat32(rv.Float()))
case reflect.Float64:
tv.SetFloat64(softfloat.Float64(math.Float64bits(rv.Float())))
tv.SetFloat64(ConvertToSoftFloat64(rv.Float()))
case reflect.Array:
rvl := rv.Len()
if rv.Type().Elem().Kind() == reflect.Uint8 {
Expand Down Expand Up @@ -1052,9 +1049,9 @@ func gno2GoValue(tv *TypedValue, rv reflect.Value) (ret reflect.Value) {
case Uint64Type:
rv.SetUint(tv.GetUint64())
case Float32Type:
rv.SetFloat(math.Float64frombits(uint64(softfloat.F32to64(tv.GetFloat32()))))
rv.SetFloat(tv.GetFloat32().Float64())
case Float64Type:
rv.SetFloat(math.Float64frombits(uint64(tv.GetFloat64())))
rv.SetFloat(tv.GetFloat64().Float64())
default:
panic(fmt.Sprintf(
"unexpected type %s",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ cat > runtime_softfloat64_test.go << EOF
EOF
cat "$GOROOT/src/runtime/softfloat64_test.go" >> ./runtime_softfloat64_test.go
sed -i 's/^package runtime_test$/package softfloat_test/
s#^\t\. "runtime"$#\t. "github.com/gnolang/gno/gnovm/pkg/gnolang/softfloat"#
s#^\t\. "runtime"$#\t. "github.com/gnolang/gno/gnovm/pkg/gnolang/internal/softfloat"#
s/GOARCH/runtime.GOARCH/g
16a\
"runtime"' runtime_softfloat64_test.go
"runtime"' runtime_softfloat64_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

70 changes: 70 additions & 0 deletions gnovm/pkg/gnolang/internal/softfloat/softfloat.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Package softfloat is a copy of the Go runtime's softfloat64.go file.
// It is a pure software floating point implementation. It can be used to
// perform determinstic, hardware-independent floating point computations.
//
// This package uses shortnames to refer to its different operations. Here is a
// quick reference:
//
// add f + g
// sub f - g
// mul f * g
// div f / g
// neg (- f)
// eq f == g
// gt f > g
// ge f >= g
package softfloat

// This file mostly exports the functions from runtime_softfloat64.go

//go:generate sh copy.sh

func Fadd64(f, g uint64) uint64 { return fadd64(f, g) }
func Fsub64(f, g uint64) uint64 { return fsub64(f, g) }
func Fmul64(f, g uint64) uint64 { return fmul64(f, g) }
func Fdiv64(f, g uint64) uint64 { return fdiv64(f, g) }
func Fneg64(f uint64) uint64 { return fneg64(f) }
func Feq64(f, g uint64) bool { return feq64(f, g) }
func Fgt64(f, g uint64) bool { return fgt64(f, g) }
func Fge64(f, g uint64) bool { return fge64(f, g) }

func Fadd32(f, g uint32) uint32 { return fadd32(f, g) }
func Fsub32(f, g uint32) uint32 { return fadd32(f, Fneg32(g)) }
func Fmul32(f, g uint32) uint32 { return fmul32(f, g) }
func Fdiv32(f, g uint32) uint32 { return fdiv32(f, g) }
func Feq32(f, g uint32) bool { return feq32(f, g) }
func Fgt32(f, g uint32) bool { return fgt32(f, g) }
func Fge32(f, g uint32) bool { return fge32(f, g) }

func Fcmp64(f, g uint64) (cmp int32, isnan bool) { return fcmp64(f, g) }

func Fneg32(f uint32) uint32 {
// Not defined in runtime - this is a copy similar to fneg64.
return f ^ (1 << (mantbits32 + expbits32))
}

// Conversions

func Fintto64(val int64) (f uint64) { return fintto64(val) }
func Fintto32(val int64) (f uint32) { return fintto32(val) }

func F32to64(f uint32) uint64 { return f32to64(f) }
func F32toint32(x uint32) int32 { return f32toint32(x) }
func F32toint64(x uint32) int64 { return f32toint64(x) }
func F32touint64(x uint32) uint64 { return f32touint64(x) }
func F64to32(f uint64) uint32 { return f64to32(f) }
func F64toint(f uint64) (val int64, ok bool) { return f64toint(f) }
func F64toint32(x uint64) int32 { return f64toint32(x) }
func F64toint64(x uint64) int64 { return f64toint64(x) }
func F64touint64(x uint64) uint64 { return f64touint64(x) }
func Fint32to32(x int32) uint32 { return fint32to32(x) }
func Fint32to64(x int32) uint64 { return fint32to64(x) }
func Fint64to32(x int64) uint32 { return fint64to32(x) }
func Fint64to64(x int64) uint64 { return fint64to64(x) }
func Fuint64to32(x uint64) uint32 { return fuint64to32(x) }
func Fuint64to64(x uint64) uint64 { return fuint64to64(x) }

// unpack64 unpacks the float64 f into sign, exp, mantissa, isInf, isNaN.

func Funpack32(f uint32) (sign, mant uint32, exp int, inf, nan bool) { return funpack32(f) }
func Funpack64(f uint64) (sign, mant uint64, exp int, inf, nan bool) { return funpack64(f) }
51 changes: 20 additions & 31 deletions gnovm/pkg/gnolang/op_binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"math/big"

"github.com/cockroachdb/apd/v3"
"github.com/gnolang/gno/gnovm/pkg/gnolang/softfloat"
)

// ----------------------------------------
Expand Down Expand Up @@ -392,11 +391,9 @@ func isEql(store Store, lv, rv *TypedValue) bool {
case Uint64Kind:
return (lv.GetUint64() == rv.GetUint64())
case Float32Kind:
cmp, nan := softfloat.Fcmp64(softfloat.F32to64(lv.GetFloat32()), softfloat.F32to64(rv.GetFloat32()))
return cmp == 0 && !nan
return lv.GetFloat32().Eq(rv.GetFloat32())
case Float64Kind:
cmp, nan := softfloat.Fcmp64(lv.GetFloat64(), rv.GetFloat64())
return cmp == 0 && !nan
return lv.GetFloat64().Eq(rv.GetFloat64())
case BigintKind:
lb := lv.V.(BigintValue).V
rb := rv.V.(BigintValue).V
Expand Down Expand Up @@ -535,11 +532,9 @@ func isLss(lv, rv *TypedValue) bool {
case Uint64Kind:
return (lv.GetUint64() < rv.GetUint64())
case Float32Kind:
cmp, nan := softfloat.Fcmp64(softfloat.F32to64(lv.GetFloat32()), softfloat.F32to64(rv.GetFloat32()))
return (cmp < 0) && !nan
return lv.GetFloat32().Lt(rv.GetFloat32())
case Float64Kind:
cmp, nan := softfloat.Fcmp64(lv.GetFloat64(), rv.GetFloat64())
return (cmp < 0) && !nan
return lv.GetFloat64().Lt(rv.GetFloat64())
case BigintKind:
lb := lv.V.(BigintValue).V
rb := rv.V.(BigintValue).V
Expand Down Expand Up @@ -581,11 +576,9 @@ func isLeq(lv, rv *TypedValue) bool {
case Uint64Kind:
return (lv.GetUint64() <= rv.GetUint64())
case Float32Kind:
cmp, nan := softfloat.Fcmp64(softfloat.F32to64(lv.GetFloat32()), softfloat.F32to64(rv.GetFloat32()))
return (cmp <= 0) && !nan
return lv.GetFloat32().Le(rv.GetFloat32())
case Float64Kind:
cmp, nan := softfloat.Fcmp64(lv.GetFloat64(), rv.GetFloat64())
return (cmp <= 0) && !nan
return lv.GetFloat64().Le(rv.GetFloat64())
case BigintKind:
lb := lv.V.(BigintValue).V
rb := rv.V.(BigintValue).V
Expand Down Expand Up @@ -627,11 +620,9 @@ func isGtr(lv, rv *TypedValue) bool {
case Uint64Kind:
return (lv.GetUint64() > rv.GetUint64())
case Float32Kind:
cmp, nan := softfloat.Fcmp64(softfloat.F32to64(lv.GetFloat32()), softfloat.F32to64(rv.GetFloat32()))
return (cmp > 0) && !nan
return lv.GetFloat32().Gt(rv.GetFloat32())
case Float64Kind:
cmp, nan := softfloat.Fcmp64(lv.GetFloat64(), rv.GetFloat64())
return (cmp > 0) && !nan
return lv.GetFloat64().Gt(rv.GetFloat64())
case BigintKind:
lb := lv.V.(BigintValue).V
rb := rv.V.(BigintValue).V
Expand Down Expand Up @@ -673,11 +664,9 @@ func isGeq(lv, rv *TypedValue) bool {
case Uint64Kind:
return (lv.GetUint64() >= rv.GetUint64())
case Float32Kind:
cmp, nan := softfloat.Fcmp64(softfloat.F32to64(lv.GetFloat32()), softfloat.F32to64(rv.GetFloat32()))
return (cmp >= 0) && !nan
return lv.GetFloat32().Ge(rv.GetFloat32())
case Float64Kind:
cmp, nan := softfloat.Fcmp64(lv.GetFloat64(), rv.GetFloat64())
return (cmp >= 0) && !nan
return lv.GetFloat64().Ge(rv.GetFloat64())
case BigintKind:
lb := lv.V.(BigintValue).V
rb := rv.V.(BigintValue).V
Expand Down Expand Up @@ -725,10 +714,10 @@ func addAssign(alloc *Allocator, lv, rv *TypedValue) {
lv.SetUint64(lv.GetUint64() + rv.GetUint64())
case Float32Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat32(softfloat.Fadd32(lv.GetFloat32(), rv.GetFloat32()))
lv.SetFloat32(lv.GetFloat32().Add(rv.GetFloat32()))
case Float64Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat64(softfloat.Fadd64(lv.GetFloat64(), rv.GetFloat64()))
lv.SetFloat64(lv.GetFloat64().Add(rv.GetFloat64()))
case BigintType, UntypedBigintType:
lb := lv.GetBigInt()
lb = big.NewInt(0).Add(lb, rv.GetBigInt())
Expand Down Expand Up @@ -781,10 +770,10 @@ func subAssign(lv, rv *TypedValue) {
lv.SetUint64(lv.GetUint64() - rv.GetUint64())
case Float32Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat32(softfloat.Fsub32(lv.GetFloat32(), rv.GetFloat32()))
lv.SetFloat32(lv.GetFloat32().Sub(rv.GetFloat32()))
case Float64Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat64(softfloat.Fsub64(lv.GetFloat64(), rv.GetFloat64()))
lv.SetFloat64(lv.GetFloat64().Sub(rv.GetFloat64()))
case BigintType, UntypedBigintType:
lb := lv.GetBigInt()
lb = big.NewInt(0).Sub(lb, rv.GetBigInt())
Expand Down Expand Up @@ -837,10 +826,10 @@ func mulAssign(lv, rv *TypedValue) {
lv.SetUint64(lv.GetUint64() * rv.GetUint64())
case Float32Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat32(softfloat.Fmul32(lv.GetFloat32(), rv.GetFloat32()))
lv.SetFloat32(lv.GetFloat32().Mul(rv.GetFloat32()))
case Float64Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat64(softfloat.Fmul64(lv.GetFloat64(), rv.GetFloat64()))
lv.SetFloat64(lv.GetFloat64().Mul(rv.GetFloat64()))
case BigintType, UntypedBigintType:
lb := lv.GetBigInt()
lb = big.NewInt(0).Mul(lb, rv.GetBigInt())
Expand Down Expand Up @@ -928,16 +917,16 @@ func quoAssign(lv, rv *TypedValue) *Exception {
lv.SetUint64(lv.GetUint64() / rv.GetUint64())
case Float32Type:
// NOTE: gno doesn't fuse *+.
if cmp, nan := softfloat.Fcmp64(softfloat.F32to64(rv.GetFloat32()), softfloat.Fint32to64(0)); cmp == 0 && !nan {
if rv.GetFloat32().Eq(0) {
return expt
}
lv.SetFloat32(softfloat.Fdiv32(lv.GetFloat32(), rv.GetFloat32()))
lv.SetFloat32(lv.GetFloat32().Div(rv.GetFloat32()))
case Float64Type:
// NOTE: gno doesn't fuse *+.
if cmp, nan := softfloat.Fcmp64(rv.GetFloat64(), 0); cmp == 0 && !nan {
if rv.GetFloat64().Eq(0) {
return expt
}
lv.SetFloat64(softfloat.Fdiv64(lv.GetFloat64(), rv.GetFloat64()))
lv.SetFloat64(lv.GetFloat64().Div(rv.GetFloat64()))
case BigintType, UntypedBigintType:
if rv.GetBigInt().Sign() == 0 {
return expt
Expand Down
Loading

0 comments on commit 8b46e01

Please sign in to comment.