Skip to content

Commit

Permalink
fix(gonative): add constant information when we define a go native va…
Browse files Browse the repository at this point in the history
…lue (gnolang#2848)

First part of the fix: gnolang#2836

The second part is addressed here:
gnolang#2731
  • Loading branch information
omarsy authored Oct 21, 2024
1 parent 13dfd21 commit 88a0c4e
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 41 deletions.
15 changes: 12 additions & 3 deletions gnovm/pkg/gnolang/gonative.go
Original file line number Diff line number Diff line change
Expand Up @@ -1258,16 +1258,25 @@ func (x *PackageNode) DefineGoNativeType(rt reflect.Type) {
x.Define(Name(name), asValue(nt))
}

func (x *PackageNode) DefineGoNativeValue(n Name, nv interface{}) {
func (x *PackageNode) DefineGoNativeValue(name Name, nv interface{}) {
x.defineGoNativeValue(false, name, nv)
}

func (x *PackageNode) DefineGoNativeConstValue(name Name, nv interface{}) {
x.defineGoNativeValue(true, name, nv)
}

func (x *PackageNode) defineGoNativeValue(isConst bool, n Name, nv interface{}) {
if debug {
debug.Printf("*PackageNode.DefineGoNativeValue(%s)\n", reflect.ValueOf(nv).String())
debug.Printf("*PackageNode.defineGoNativeValue(%s)\n", reflect.ValueOf(nv).String())
}
rv := reflect.ValueOf(nv)
// rv is not settable, so create something that is.
rt := rv.Type()
rv2 := reflect.New(rt).Elem()
rv2.Set(rv)
x.Define(n, go2GnoValue(nilAllocator, rv2))
tv := go2GnoValue(nilAllocator, rv2)
x.Define2(isConst, n, tv.T, tv)
}

// ----------------------------------------
Expand Down
4 changes: 4 additions & 0 deletions gnovm/pkg/gnolang/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -2093,6 +2093,10 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node {
// General case: a, b = x, y.
for i, lx := range n.Lhs {
lt := evalStaticTypeOf(store, last, lx)
if nt, ok := lt.(*NativeType); ok && nt.Kind() == FuncKind {
panic(fmt.Sprintf("cannot assign to %s (neither addressable nor a map index expression)", lx))
}

// if lt is interface, nothing will happen
checkOrConvertType(store, last, &n.Rhs[i], lt, true)
}
Expand Down
8 changes: 4 additions & 4 deletions gnovm/pkg/gnolang/preprocess_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (

func TestPreprocess_BinaryExpressionOneNative(t *testing.T) {
pn := NewPackageNode("time", "time", nil)
pn.DefineGoNativeValue("Millisecond", time.Millisecond)
pn.DefineGoNativeValue("Second", time.Second)
pn.DefineGoNativeConstValue("Millisecond", time.Millisecond)
pn.DefineGoNativeConstValue("Second", time.Second)
pn.DefineGoNativeType(reflect.TypeOf(time.Duration(0)))
pv := pn.NewPackage()
store := gonativeTestStore(pn, pv)
Expand All @@ -37,8 +37,8 @@ func main() {

func TestPreprocess_BinaryExpressionBothNative(t *testing.T) {
pn := NewPackageNode("time", "time", nil)
pn.DefineGoNativeValue("March", time.March)
pn.DefineGoNativeValue("Wednesday", time.Wednesday)
pn.DefineGoNativeConstValue("March", time.March)
pn.DefineGoNativeConstValue("Wednesday", time.Wednesday)
pn.DefineGoNativeType(reflect.TypeOf(time.Month(0)))
pn.DefineGoNativeType(reflect.TypeOf(time.Weekday(0)))
pv := pn.NewPackage()
Expand Down
14 changes: 14 additions & 0 deletions gnovm/tests/files/assign29_native.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package main

import (
"time"
)

func main() {
time.Now = func() time.Time {
return time.Time{}
}
}

// Error:
// main/files/assign29_native.gno:8:2: cannot assign to time<VPBlock(2,0)>.Now (neither addressable nor a map index expression)
67 changes: 33 additions & 34 deletions gnovm/tests/imports.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,23 +222,23 @@ func TestStore(rootDir, filesPath string, stdin io.Reader, stdout, stderr io.Wri
return pkg, pkg.NewPackage()
case "time":
pkg := gno.NewPackageNode("time", pkgPath, nil)
pkg.DefineGoNativeValue("Millisecond", time.Millisecond)
pkg.DefineGoNativeValue("Second", time.Second)
pkg.DefineGoNativeValue("Minute", time.Minute)
pkg.DefineGoNativeValue("Hour", time.Hour)
pkg.DefineGoNativeValue("Date", time.Date)
pkg.DefineGoNativeValue("Now", func() time.Time { return time.Unix(0, 0).UTC() }) // deterministic
pkg.DefineGoNativeValue("January", time.January)
pkg.DefineGoNativeValue("February", time.February)
pkg.DefineGoNativeValue("March", time.March)
pkg.DefineGoNativeValue("April", time.April)
pkg.DefineGoNativeValue("May", time.May)
pkg.DefineGoNativeValue("June", time.June)
pkg.DefineGoNativeValue("July", time.July)
pkg.DefineGoNativeValue("August", time.August)
pkg.DefineGoNativeValue("September", time.September)
pkg.DefineGoNativeValue("November", time.November)
pkg.DefineGoNativeValue("December", time.December)
pkg.DefineGoNativeConstValue("Millisecond", time.Millisecond)
pkg.DefineGoNativeConstValue("Second", time.Second)
pkg.DefineGoNativeConstValue("Minute", time.Minute)
pkg.DefineGoNativeConstValue("Hour", time.Hour)
pkg.DefineGoNativeConstValue("Date", time.Date)
pkg.DefineGoNativeConstValue("Now", func() time.Time { return time.Unix(0, 0).UTC() }) // deterministic
pkg.DefineGoNativeConstValue("January", time.January)
pkg.DefineGoNativeConstValue("February", time.February)
pkg.DefineGoNativeConstValue("March", time.March)
pkg.DefineGoNativeConstValue("April", time.April)
pkg.DefineGoNativeConstValue("May", time.May)
pkg.DefineGoNativeConstValue("June", time.June)
pkg.DefineGoNativeConstValue("July", time.July)
pkg.DefineGoNativeConstValue("August", time.August)
pkg.DefineGoNativeConstValue("September", time.September)
pkg.DefineGoNativeConstValue("November", time.November)
pkg.DefineGoNativeConstValue("December", time.December)
pkg.DefineGoNativeValue("UTC", time.UTC)
pkg.DefineGoNativeValue("Unix", time.Unix)
pkg.DefineGoNativeType(reflect.TypeOf(time.Time{}))
Expand Down Expand Up @@ -272,21 +272,20 @@ func TestStore(rootDir, filesPath string, stdin io.Reader, stdout, stderr io.Wri
pkg := gno.NewPackageNode("math", pkgPath, nil)
pkg.DefineGoNativeValue("Abs", math.Abs)
pkg.DefineGoNativeValue("Cos", math.Cos)
pkg.DefineGoNativeValue("Pi", math.Pi)
pkg.DefineGoNativeConstValue("Pi", math.Pi)
pkg.DefineGoNativeValue("Float64bits", math.Float64bits)
pkg.DefineGoNativeValue("Pi", math.Pi)
pkg.DefineGoNativeValue("MaxFloat32", math.MaxFloat32)
pkg.DefineGoNativeValue("MaxFloat64", math.MaxFloat64)
pkg.DefineGoNativeValue("MaxUint32", uint32(math.MaxUint32))
pkg.DefineGoNativeValue("MaxUint64", uint64(math.MaxUint64))
pkg.DefineGoNativeValue("MinInt8", math.MinInt8)
pkg.DefineGoNativeValue("MinInt16", math.MinInt16)
pkg.DefineGoNativeValue("MinInt32", math.MinInt32)
pkg.DefineGoNativeValue("MinInt64", int64(math.MinInt64))
pkg.DefineGoNativeValue("MaxInt8", math.MaxInt8)
pkg.DefineGoNativeValue("MaxInt16", math.MaxInt16)
pkg.DefineGoNativeValue("MaxInt32", math.MaxInt32)
pkg.DefineGoNativeValue("MaxInt64", int64(math.MaxInt64))
pkg.DefineGoNativeConstValue("MaxFloat32", math.MaxFloat32)
pkg.DefineGoNativeConstValue("MaxFloat64", math.MaxFloat64)
pkg.DefineGoNativeConstValue("MaxUint32", uint32(math.MaxUint32))
pkg.DefineGoNativeConstValue("MaxUint64", uint64(math.MaxUint64))
pkg.DefineGoNativeConstValue("MinInt8", math.MinInt8)
pkg.DefineGoNativeConstValue("MinInt16", math.MinInt16)
pkg.DefineGoNativeConstValue("MinInt32", math.MinInt32)
pkg.DefineGoNativeConstValue("MinInt64", int64(math.MinInt64))
pkg.DefineGoNativeConstValue("MaxInt8", math.MaxInt8)
pkg.DefineGoNativeConstValue("MaxInt16", math.MaxInt16)
pkg.DefineGoNativeConstValue("MaxInt32", math.MaxInt32)
pkg.DefineGoNativeConstValue("MaxInt64", int64(math.MaxInt64))
return pkg, pkg.NewPackage()
case "math/rand":
// XXX only expose for tests.
Expand Down Expand Up @@ -321,13 +320,13 @@ func TestStore(rootDir, filesPath string, stdin io.Reader, stdout, stderr io.Wri
return pkg, pkg.NewPackage()
case "compress/flate":
pkg := gno.NewPackageNode("flate", pkgPath, nil)
pkg.DefineGoNativeValue("BestSpeed", flate.BestSpeed)
pkg.DefineGoNativeConstValue("BestSpeed", flate.BestSpeed)
return pkg, pkg.NewPackage()
case "compress/gzip":
pkg := gno.NewPackageNode("gzip", pkgPath, nil)
pkg.DefineGoNativeType(reflect.TypeOf(gzip.Writer{}))
pkg.DefineGoNativeValue("BestCompression", gzip.BestCompression)
pkg.DefineGoNativeValue("BestSpeed", gzip.BestSpeed)
pkg.DefineGoNativeConstValue("BestCompression", gzip.BestCompression)
pkg.DefineGoNativeConstValue("BestSpeed", gzip.BestSpeed)
return pkg, pkg.NewPackage()
case "context":
pkg := gno.NewPackageNode("context", pkgPath, nil)
Expand Down

0 comments on commit 88a0c4e

Please sign in to comment.