Given the following code:
package foo
var A = f()
var B int
func Main() int {
return B
}
func f() int {
B = 3
return B
}
the resulting opcodes generated for it will be:
INDEX OPCODE PARAMETER
0 INITSSLOT 2 <<
2 CALL 10 (8/08)
4 STSFLD0
5 PUSH0
6 STSFLD1
7 RET
8 LDSFLD1
9 RET
10 PUSH3
11 STSFLD1
12 LDSFLD1
13 RET
Global variables initialisation is being performed by this code:
|
for i := range t.Names { |
|
if len(t.Values) != 0 { |
|
if i == 0 || !multiRet { |
|
ast.Walk(c, t.Values[i]) |
|
} |
|
} else { |
|
c.emitDefault(c.typeOf(t.Type)) |
|
} |
|
c.emitStoreVar("", t.Names[i].Name) |
|
} |
So firstly
A is initialized by the call to
f() and
3 is stored in the 1-st cell of the static slot as
B's value. After that
B is initialized by default value and
0 overwrites the previously stored
3. As a result, the program leaves
0 on stack, which is wrong.
We need to initialize global variable by default value only if there's no value stored for it yet.
Given the following code:
the resulting opcodes generated for it will be:
Global variables initialisation is being performed by this code:
neo-go/pkg/compiler/codegen.go
Lines 599 to 608 in e31c3b5
Ais initialized by the call tof()and3is stored in the 1-st cell of the static slot asB's value. After thatBis initialized by default value and0overwrites the previously stored3. As a result, the program leaves0on stack, which is wrong.We need to initialize global variable by default value only if there's no value stored for it yet.