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() { func main() {
var buf [4]byte var buf [4]byte
//fmt.Println(buf) //fmt.Println(buf)
s := base64.RawStdEncoding.EncodeToString(buf) s := base64.RawStdEncoding.EncodeToString(buf[:])
//fmt.Println(base64.RawStdEncoding) //fmt.Println(base64.RawStdEncoding)
fmt.Println(s) fmt.Println(s)
} }

View File

@@ -25,7 +25,7 @@ func main() {
BrowserXssFilter: true, BrowserXssFilter: true,
ContentSecurityPolicy: "script-src $NONCE", 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"`, 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) app := secureMiddleware.Handler(myHandler)

View File

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

View File

@@ -114,6 +114,26 @@ func main() {
// 2 5 // 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() { func Example_a2() {
src := ` src := `
package main package main
@@ -334,6 +354,20 @@ func main() {
// false true // 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() { func Example_chan0() {
src := ` src := `
package main package main
@@ -944,6 +978,24 @@ func main() {
// Hello 42 // 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() { func Example_init0() {
src := ` src := `
package main package main
@@ -1026,7 +1078,7 @@ import (
func main() { func main() {
var buf [4]byte var buf [4]byte
//fmt.Println(buf) //fmt.Println(buf)
s := base64.RawStdEncoding.EncodeToString(buf) s := base64.RawStdEncoding.EncodeToString(buf[:])
//fmt.Println(base64.RawStdEncoding) //fmt.Println(base64.RawStdEncoding)
fmt.Println(s) fmt.Println(s)
}` }`
@@ -2871,6 +2923,28 @@ func main() {
// 7 8 // 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() { func Example_switch() {
src := ` src := `
package main package main

View File

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

View File

@@ -124,8 +124,17 @@ func nodeType(interp *Interpreter, scope *Scope, n *Node) *Type {
t.cat = ArrayT t.cat = ArrayT
if len(n.child) > 1 { if len(n.child) > 1 {
// An array size is defined // 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]) t.val = nodeType(interp, scope, n.child[1])
log.Println(n.index, t.val.cat, t.size)
} else { } else {
t.val = nodeType(interp, scope, n.child[0]) t.val = nodeType(interp, scope, n.child[0])
} }