]> Cypherpunks.ru repositories - gostls13.git/blob - test/closure.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / closure.go
1 // run
2
3 // Copyright 2009 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 // Test the behavior of closures.
8
9 package main
10
11 import "runtime"
12
13 var c = make(chan int)
14
15 func check(a []int) {
16         for i := 0; i < len(a); i++ {
17                 n := <-c
18                 if n != a[i] {
19                         println("want", a[i], "got", n, "at", i)
20                         panic("fail")
21                 }
22         }
23 }
24
25 func f() {
26         var i, j int
27
28         i = 1
29         j = 2
30         f := func() {
31                 c <- i
32                 i = 4
33                 g := func() {
34                         c <- i
35                         c <- j
36                 }
37                 g()
38                 c <- i
39         }
40         j = 5
41         f()
42 }
43
44 // Accumulator generator
45 func accum(n int) func(int) int {
46         return func(i int) int {
47                 n += i
48                 return n
49         }
50 }
51
52 func g(a, b func(int) int) {
53         c <- a(2)
54         c <- b(3)
55         c <- a(4)
56         c <- b(5)
57 }
58
59 func h() {
60         var x8 byte = 100
61         var x64 int64 = 200
62
63         c <- int(x8)
64         c <- int(x64)
65         f := func(z int) {
66                 g := func() {
67                         c <- int(x8)
68                         c <- int(x64)
69                         c <- z
70                 }
71                 g()
72                 c <- int(x8)
73                 c <- int(x64)
74                 c <- int(z)
75         }
76         x8 = 101
77         x64 = 201
78         f(500)
79 }
80
81 func newfunc() func(int) int { return func(x int) int { return x } }
82
83 func main() {
84         runtime.GOMAXPROCS(1)
85         var fail bool
86
87         go f()
88         check([]int{1, 4, 5, 4})
89
90         a := accum(0)
91         b := accum(1)
92         go g(a, b)
93         check([]int{2, 4, 6, 9})
94
95         go h()
96         check([]int{100, 200, 101, 201, 500, 101, 201, 500})
97
98         memstats := new(runtime.MemStats)
99         runtime.ReadMemStats(memstats)
100         n0 := memstats.Mallocs
101
102         x, y := newfunc(), newfunc()
103         if x(1) != 1 || y(2) != 2 {
104                 println("newfunc returned broken funcs")
105                 fail = true
106         }
107
108         runtime.ReadMemStats(memstats)
109         if n0 != memstats.Mallocs {
110                 println("newfunc allocated unexpectedly")
111                 fail = true
112         }
113
114         ff(1)
115
116         if fail {
117                 panic("fail")
118         }
119 }
120
121 func ff(x int) {
122         call(func() {
123                 _ = x
124         })
125 }
126
127 func call(func()) {
128 }