diff --git a/gnovm/pkg/gnolang/gno_test.go b/gnovm/pkg/gnolang/gno_test.go index 24a92a81312..54d808faefc 100644 --- a/gnovm/pkg/gnolang/gno_test.go +++ b/gnovm/pkg/gnolang/gno_test.go @@ -159,6 +159,38 @@ func main() { m.RunMain() } +func BenchmarkPreprocessForLoop(b *testing.B) { + m := NewMachine("test", nil) + c := `package test +func main() { + for i:=0; i<10000; i++ {} +}` + n := MustParseFile("main.go", c) + m.RunFiles(n) + + for i := 0; i < b.N; i++ { + m.RunMain() + } +} + +func BenchmarkIfStatement(b *testing.B) { + m := NewMachine("test", nil) + c := `package test +func main() { + for i:=0; i<10000; i++ { + if i > 10 { + + } + } +}` + n := MustParseFile("main.go", c) + m.RunFiles(n) + + for i := 0; i < b.N; i++ { + m.RunMain() + } +} + func TestDoOpEvalBaseConversion(t *testing.T) { m := NewMachine("test", nil) diff --git a/gnovm/pkg/gnolang/op_inc_dec.go b/gnovm/pkg/gnolang/op_inc_dec.go index 84c39716eec..7a8a885bcf0 100644 --- a/gnovm/pkg/gnolang/op_inc_dec.go +++ b/gnovm/pkg/gnolang/op_inc_dec.go @@ -26,6 +26,10 @@ func (m *Machine) doOpInc() { panic("expected lv.V to be nil for primitive type for OpInc") } } + + // here we can't just switch on the value type + // because it could be a type alias + // type num int switch baseOf(lv.T) { case IntType: lv.SetInt(lv.GetInt() + 1) diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index 8aca0058dcd..8eb2b37fcc2 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -1253,7 +1253,7 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { case StringKind, ArrayKind, SliceKind: // Replace const index with int *ConstExpr, // or if not const, assert integer type.. - checkOrConvertIntegerType(store, last, n.Index) + checkOrConvertIntegerKind(store, last, n.Index) case MapKind: mt := baseOf(gnoTypeOf(store, dt)).(*MapType) checkOrConvertType(store, last, &n.Index, mt.Key, false) @@ -1267,9 +1267,9 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { case *SliceExpr: // Replace const L/H/M with int *ConstExpr, // or if not const, assert integer type.. - checkOrConvertIntegerType(store, last, n.Low) - checkOrConvertIntegerType(store, last, n.High) - checkOrConvertIntegerType(store, last, n.Max) + checkOrConvertIntegerKind(store, last, n.Low) + checkOrConvertIntegerKind(store, last, n.High) + checkOrConvertIntegerKind(store, last, n.Max) // TRANS_LEAVE ----------------------- case *TypeAssertExpr: @@ -1728,12 +1728,12 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { // TRANS_LEAVE ----------------------- case *ForStmt: // Cond consts become bool *ConstExprs. - checkOrConvertType(store, last, &n.Cond, BoolType, false) + checkOrConvertBoolKind(store, last, n.Cond) // TRANS_LEAVE ----------------------- case *IfStmt: // Cond consts become bool *ConstExprs. - checkOrConvertType(store, last, &n.Cond, BoolType, false) + checkOrConvertBoolKind(store, last, n.Cond) // TRANS_LEAVE ----------------------- case *RangeStmt: @@ -2474,7 +2474,7 @@ func checkOrConvertType(store Store, last BlockNode, x *Expr, t Type, autoNative // autoNative is usually false, but set to true // for native function calls, where gno values are // automatically converted to native go types. -// NOTE: also see checkOrConvertIntegerType() +// NOTE: also see checkOrConvertIntegerKind() func convertType(store Store, last BlockNode, x *Expr, t Type) { if debug { debug.Printf("convertType, *x: %v:, t:%v \n", *x, t) @@ -2783,18 +2783,40 @@ func findUndefined2(store Store, last BlockNode, x Expr, t Type) (un Name) { return } -// like checkOrConvertType() but for any integer type. -func checkOrConvertIntegerType(store Store, last BlockNode, x Expr) { +// like checkOrConvertType() but for any typed bool kind. +func checkOrConvertBoolKind(store Store, last BlockNode, x Expr) { + if cx, ok := x.(*ConstExpr); ok { + convertConst(store, last, cx, BoolType) + } else if x != nil { + xt := evalStaticTypeOf(store, last, x) + checkBoolKind(xt) + } +} + +// assert that xt is a typed bool kind. +func checkBoolKind(xt Type) { + switch xt.Kind() { + case BoolKind: + return // ok + default: + panic(fmt.Sprintf( + "expected typed bool kind, but got %v", + xt.Kind())) + } +} + +// like checkOrConvertType() but for any typed integer kind. +func checkOrConvertIntegerKind(store Store, last BlockNode, x Expr) { if cx, ok := x.(*ConstExpr); ok { convertConst(store, last, cx, IntType) } else if x != nil { xt := evalStaticTypeOf(store, last, x) - checkIntegerType(xt) + checkIntegerKind(xt) } } -// assert that xt can be assigned as an integer type. -func checkIntegerType(xt Type) { +// assert that xt is a typed integer kind. +func checkIntegerKind(xt Type) { switch xt.Kind() { case IntKind, Int8Kind, Int16Kind, Int32Kind, Int64Kind, UintKind, Uint8Kind, Uint16Kind, Uint32Kind, Uint64Kind, @@ -2802,7 +2824,7 @@ func checkIntegerType(xt Type) { return // ok default: panic(fmt.Sprintf( - "expected integer type, but got %v", + "expected typed integer kind, but got %v", xt.Kind())) } } diff --git a/gnovm/tests/files/for7.gno b/gnovm/tests/files/for7.gno index 92ad5f3ce34..0f471956314 100644 --- a/gnovm/tests/files/for7.gno +++ b/gnovm/tests/files/for7.gno @@ -6,4 +6,4 @@ func main() { } // Error: -// main/files/for7.gno:4: cannot use int as bool +// main/files/for7.gno:4: expected typed bool kind, but got IntKind diff --git a/gnovm/tests/files/if2.gno b/gnovm/tests/files/if2.gno index 88261c520c9..bc417a92fe7 100644 --- a/gnovm/tests/files/if2.gno +++ b/gnovm/tests/files/if2.gno @@ -10,4 +10,4 @@ func main() { } // Error: -// main/files/if2.gno:7: cannot use int as bool +// main/files/if2.gno:7: expected typed bool kind, but got IntKind