Skip to content

Commit

Permalink
interp: check linkname var
Browse files Browse the repository at this point in the history
  • Loading branch information
visualfc committed Mar 23, 2023
1 parent bc1d375 commit 94dab4a
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 14 deletions.
28 changes: 23 additions & 5 deletions interp.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ package igop

import (
"fmt"
"go/ast"
"go/constant"
"go/token"
"go/types"
Expand Down Expand Up @@ -82,7 +83,7 @@ type Interp struct {
ctx *Context
mainpkg *ssa.Package // the SSA main package
record *TypesRecord // lookup type and ToType
globals map[ssa.Value]value // addresses of global variables (immutable)
globals map[string]value // addresses of global variables (immutable)
preloadTypes map[types.Type]reflect.Type // preload types.Type -> reflect.Type
funcs map[*ssa.Function]*function // ssa.Function -> *function
msets map[reflect.Type](map[string]*ssa.Function) // user defined type method sets
Expand Down Expand Up @@ -1145,7 +1146,7 @@ func newInterp(ctx *Context, mainpkg *ssa.Package, globals map[string]interface{
i := &Interp{
ctx: ctx,
mainpkg: mainpkg,
globals: make(map[ssa.Value]value),
globals: make(map[string]value),
goroutines: 1,
preloadTypes: make(map[types.Type]reflect.Type),
funcs: make(map[*ssa.Function]*function),
Expand All @@ -1157,6 +1158,7 @@ func newInterp(ctx *Context, mainpkg *ssa.Package, globals map[string]interface{
i.record.Load(mainpkg)

var pkgs []*ssa.Package

for _, pkg := range mainpkg.Prog.AllPackages() {
// skip external pkg
if pkg.Func("init").Blocks == nil {
Expand All @@ -1168,13 +1170,29 @@ func newInterp(ctx *Context, mainpkg *ssa.Package, globals map[string]interface{
switch v := m.(type) {
case *ssa.Global:
typ := i.preToType(deref(v.Type()))
i.globals[v] = reflect.New(typ).Interface()
i.globals[v.String()] = reflect.New(typ).Interface()
}
}
}
// check linkname var
for _, sp := range i.ctx.pkgs {
for _, link := range sp.Links {
if link.Kind == ast.Var {
localName, targetName := link.PkgPath+"."+link.Name, link.Linkname.PkgPath+"."+link.Linkname.Name
if _, ok := i.globals[localName]; ok {
if v, ok := findExternValue(i, targetName); ok && v.Kind() == reflect.Ptr {
i.globals[localName] = v.Interface()
} else if v, ok := i.globals[targetName]; ok {
i.globals[localName] = v
}
}
}
}
}
// check globals for repl
if globals != nil {
for k := range i.globals {
if fv, ok := globals[k.String()]; ok {
if fv, ok := globals[k]; ok {
i.globals[k] = fv
}
}
Expand Down Expand Up @@ -1306,7 +1324,7 @@ func (i *Interp) GetVarAddr(key string) (interface{}, bool) {
if !ok {
return nil, false
}
p, ok := i.globals[v]
p, ok := i.globals[v.String()]
return p, ok
}

Expand Down
2 changes: 2 additions & 0 deletions load/linkname.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
)

type LinkSym struct {
Kind ast.ObjKind
PkgPath string
Name string
Linkname Linkname
Expand Down Expand Up @@ -109,6 +110,7 @@ func parseLinknameComment(pkgPath string, file *ast.File, comment *ast.Comment,
}
}
return &LinkSym{
Kind: obj.Kind,
PkgPath: pkgPath,
Name: localName,
Linkname: Linkname{PkgPath: linkPkg, Name: linkName, Recv: recv, Method: method},
Expand Down
12 changes: 6 additions & 6 deletions opblock.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,12 +239,12 @@ func (p *function) regInstr(v ssa.Value) uint32 {
return i
}

func findUserFunc(interp *Interp, fnName string) (ext reflect.Value, ok bool) {
// check override func
ext, ok = interp.ctx.override[fnName]
func findExternValue(interp *Interp, name string) (ext reflect.Value, ok bool) {
// check override value
ext, ok = interp.ctx.override[name]
if !ok {
// check extern func
ext, ok = externValues[fnName]
// check extern value
ext, ok = externValues[name]
}
return
}
Expand Down Expand Up @@ -275,7 +275,7 @@ func checkFuncCompatible(t1, t2 reflect.Type) bool {

func findExternFunc(interp *Interp, fn *ssa.Function) (ext reflect.Value, ok bool) {
fnName := fn.String()
ext, ok = findUserFunc(interp, fnName)
ext, ok = findExternValue(interp, fnName)
if ok {
typ := interp.preToType(fn.Type())
ftyp := ext.Type()
Expand Down
2 changes: 1 addition & 1 deletion ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func globalToValue(i *Interp, key *ssa.Global) (interface{}, bool) {
}
}
}
if v, ok := i.globals[key]; ok {
if v, ok := i.globals[key.String()]; ok {
return v, true
}
return nil, false
Expand Down
2 changes: 1 addition & 1 deletion repl.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ func (r *Repl) eval(tok token.Token, expr string) (err error) {
r.fsInit = rinit
r.fsMain = rmain
for k, v := range i.globals {
r.globalMap[k.String()] = v
r.globalMap[k] = v
}
if inMain {
r.infuncs = append(r.infuncs, expr)
Expand Down
2 changes: 1 addition & 1 deletion visit.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func wrapMethodType(sig *types.Signature) *types.Signature {
}

func (visit *visitor) findLinkFunc(sym *load.LinkSym) (ext reflect.Value, ok bool) {
ext, ok = findUserFunc(visit.intp, sym.Linkname.PkgPath+"."+sym.Linkname.Name)
ext, ok = findExternValue(visit.intp, sym.Linkname.PkgPath+"."+sym.Linkname.Name)
if ok {
return
}
Expand Down

0 comments on commit 94dab4a

Please sign in to comment.