Fix regressions in variables assignments

This commit is contained in:
Marc Vertes
2018-09-11 19:28:08 +02:00
parent 127a3e3a61
commit adbcd2ec2d
9 changed files with 130 additions and 16 deletions

13
_test/a14.go Normal file
View File

@@ -0,0 +1,13 @@
package main
import "fmt"
const size = 12
func main() {
var buf [size]int
fmt.Println(buf)
}
// Output:
// [0 0 0 0 0 0 0 0 0 0 0 0]

7
_test/bool0.go Normal file
View File

@@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println(true)
}

11
_test/inc.go Normal file
View File

@@ -0,0 +1,11 @@
package main
func main() {
i := 2
//i++
i = i + 1
println(i)
}
// Output:
// 3

View File

@@ -8,7 +8,7 @@ import (
func main() {
var buf [4]byte
//fmt.Println(buf)
s := base64.RawStdEncoding.EncodeToString(buf)
s := base64.RawStdEncoding.EncodeToString(buf[:])
//fmt.Println(base64.RawStdEncoding)
fmt.Println(s)
}

View File

@@ -25,7 +25,7 @@ func main() {
BrowserXssFilter: true,
ContentSecurityPolicy: "script-src $NONCE",
PublicKey: `pin-sha256="base64+primary=="; pin-sha256="base64+backup=="; max-age=5184000; includeSubdomains; report-uri="https://www.example.com/hpkp-report"`,
//IsDevelopment: true,
IsDevelopment: true,
})
app := secureMiddleware.Handler(myHandler)

View File

@@ -218,25 +218,29 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
if n.kind == Define {
// Force definition of assigned ident in current scope
name := n.child[0].ident
n.child[0].val = n.child[1].val
n.child[0].typ = n.child[1].typ
if scope.global {
if sym, _, ok := scope.lookup(name); ok {
n.child[0].findex = sym.index
} else {
interp.fsize++
scope.size = interp.fsize
scope.sym[name] = &Symbol{index: scope.size, global: true}
scope.sym[name] = &Symbol{index: scope.size, global: true, kind: Var}
n.child[0].findex = scope.size
}
} else {
scope.size++
scope.sym[name] = &Symbol{index: scope.size}
scope.sym[name] = &Symbol{index: scope.size, kind: Var}
n.child[0].findex = scope.size
}
n.child[0].typ = n.child[1].typ
if n.child[1].action == GetFunc {
scope.sym[name].index = -1
scope.sym[name].node = n.child[1]
}
if n.child[1].kind == BasicLit {
scope.sym[name].val = n.child[1].val
}
}
n.findex = n.child[0].findex
n.val = n.child[0].val
@@ -311,7 +315,7 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
} else {
scope.size++
}
scope.sym[c.ident] = &Symbol{index: scope.size, typ: types[i], global: scope.global}
scope.sym[c.ident] = &Symbol{index: scope.size, typ: types[i], global: scope.global, kind: Var}
c.findex = scope.size
}
}
@@ -715,7 +719,7 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
n.kind = sym.node.kind
} else {
n.sym = sym
if sym.val != nil {
if sym.kind == Const && sym.val != nil {
n.val = sym.val
n.kind = BasicLit
} else if n.ident == "iota" {
@@ -736,13 +740,13 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
} else {
scope.size++
}
scope.sym[n.ident] = &Symbol{index: scope.size, global: scope.global}
scope.sym[n.ident] = &Symbol{index: scope.size, global: scope.global, kind: Var}
n.findex = scope.size
} else {
// symbol may be defined globally elsewhere later, add an entry at pkg level
interp.fsize++
interp.scope[pkgName].size = interp.fsize
interp.scope[pkgName].sym[n.ident] = &Symbol{index: interp.fsize, global: true}
interp.scope[pkgName].sym[n.ident] = &Symbol{index: interp.fsize, global: true, kind: Var}
n.sym = interp.scope[pkgName].sym[n.ident]
n.level = scope.level
n.findex = interp.fsize

View File

@@ -114,6 +114,26 @@ func main() {
// 2 5
}
func Example_a14() {
src := `
package main
import "fmt"
const size = 12
func main() {
var buf [size]int
fmt.Println(buf)
}
`
i := NewInterpreter(Opt{Entry: "main"})
i.Eval(src)
// Output:
// [0 0 0 0 0 0 0 0 0 0 0 0]
}
func Example_a2() {
src := `
package main
@@ -334,6 +354,20 @@ func main() {
// false true
}
func Example_bool0() {
src := `
package main
import "fmt"
func main() {
fmt.Println(true)
}`
i := NewInterpreter(Opt{Entry: "main"})
i.Eval(src)
}
func Example_chan0() {
src := `
package main
@@ -944,6 +978,24 @@ func main() {
// Hello 42
}
func Example_inc() {
src := `
package main
func main() {
i := 2
//i++
i = i + 1
println(i)
}
`
i := NewInterpreter(Opt{Entry: "main"})
i.Eval(src)
// Output:
// 3
}
func Example_init0() {
src := `
package main
@@ -1026,7 +1078,7 @@ import (
func main() {
var buf [4]byte
//fmt.Println(buf)
s := base64.RawStdEncoding.EncodeToString(buf)
s := base64.RawStdEncoding.EncodeToString(buf[:])
//fmt.Println(base64.RawStdEncoding)
fmt.Println(s)
}`
@@ -2871,6 +2923,28 @@ func main() {
// 7 8
}
func Example_struct7() {
src := `
package main
type Opt struct {
b bool
}
type T struct {
i int
opt Opt
}
func main() {
a := T{}
println(a.i, a.opt.b)
}`
i := NewInterpreter(Opt{Entry: "main"})
i.Eval(src)
}
func Example_switch() {
src := `
package main

View File

@@ -215,18 +215,13 @@ func indirectAssign(n *Node, f *Frame) {
// assign implements single value assignement
func assign(n *Node, f *Frame) {
//log.Println(n.index, "assign", n.child[0].ident, n.child[0].typ)
*addrValue(n, f) = value(n.child[1], f)
if n.child[0].typ == nil {
log.Println(n.child[1].typ, reflect.TypeOf(value(n.child[1], f)).Kind())
}
}
// assign0 implements assignement of zero value
func assign0(n *Node, f *Frame) {
l := len(n.child) - 1
z := n.typ.zero()
//log.Println(n.index, "in assign0", l, z, n.typ)
for _, c := range n.child[:l] {
*addrValue(c, f) = z
}
@@ -411,6 +406,7 @@ func callBin(n *Node, f *Frame) {
for i, c := range n.child[1:] {
v := value(c, f)
if c.typ == nil {
log.Println(n.index, "unset type", c.index, c.ident)
// FIXME: Temporary attempt to fix undefined type which should not occur at exec
c.typ = c.sym.typ
}

View File

@@ -124,8 +124,17 @@ func nodeType(interp *Interpreter, scope *Scope, n *Node) *Type {
t.cat = ArrayT
if len(n.child) > 1 {
// An array size is defined
t.size = n.child[0].val.(int)
var ok bool
if t.size, ok = n.child[0].val.(int); !ok {
if sym, _, ok := scope.lookup(n.child[0].ident); ok {
// Resolve symbol to get size value
if sym.typ.cat == IntT {
t.size = sym.val.(int)
}
}
}
t.val = nodeType(interp, scope, n.child[1])
log.Println(n.index, t.val.cat, t.size)
} else {
t.val = nodeType(interp, scope, n.child[0])
}