Skip to content

Commit

Permalink
Merge pull request #240 from goplus/release
Browse files Browse the repository at this point in the history
support creator multiple interp
  • Loading branch information
visualfc authored Apr 28, 2023
2 parents 96f77c5 + 00969f4 commit 1d6c597
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 33 deletions.
15 changes: 15 additions & 0 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@ func NewContext(mode Mode) *Context {
return ctx
}

func (ctx *Context) UnsafeRelease() {
ctx.pkgs = nil
ctx.Loader = nil
ctx.override = nil
}

func (ctx *Context) IsEvalMode() bool {
return ctx.evalMode
}
Expand Down Expand Up @@ -424,6 +430,14 @@ func (ctx *Context) parseGoFiles(dir string, filenames []string) ([]*ast.File, e
return files, nil
}

func (ctx *Context) LoadInterp(filename string, src interface{}) (*Interp, error) {
pkg, err := ctx.LoadFile(filename, src)
if err != nil {
return nil, err
}
return ctx.NewInterp(pkg)
}

func (ctx *Context) LoadFile(filename string, src interface{}) (*ssa.Package, error) {
file, err := ctx.ParseFile(filename, src)
if err != nil {
Expand Down Expand Up @@ -504,6 +518,7 @@ func (ctx *Context) RunPkg(mainPkg *ssa.Package, input string, args []string) (e
if err != nil {
return 2, err
}
defer interp.UnsafeReleaseIcall()
return ctx.RunInterp(interp, input, args)
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.14
require (
github.com/goplus/gop v1.1.4-0.20230225130145-e37691ce5fea
github.com/goplus/gox v1.11.32
github.com/goplus/reflectx v1.0.0
github.com/goplus/reflectx v1.1.1
github.com/modern-go/reflect2 v1.0.2
github.com/peterh/liner v1.2.2
github.com/qiniu/x v1.11.9
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ github.com/goplus/gox v1.11.32/go.mod h1:hdKq5ghywtKWnBJNQNVBkPITmWCqCFRwwd2LTYT
github.com/goplus/libc v0.3.13/go.mod h1:xqG4/g3ilKBE/UDn5vkaE7RRQPQPyspj7ecuMuvlQJ8=
github.com/goplus/mod v0.9.12 h1:CjgBGQIYqUTPGl3MrAS5CICzJwxbIfSa4OlEb141Gs4=
github.com/goplus/mod v0.9.12/go.mod h1:YoPIowz71rnLLROA4YG0AC8bzDtPRyMaQwgTRLr8ri4=
github.com/goplus/reflectx v1.0.0 h1:7KXnjojn5uM9ErYs/T9sf7+fdmO7obmpouMnOBhFBQE=
github.com/goplus/reflectx v1.0.0/go.mod h1:wHOS9ilbB4zrecI0W1dMmkW9JMcpXV7VjALVbNU9xfM=
github.com/goplus/reflectx v1.1.1 h1:4acdcG7+uIHdl7le1vAEt9M2HwGWNlVqv1fd4YsdCg0=
github.com/goplus/reflectx v1.1.1/go.mod h1:wHOS9ilbB4zrecI0W1dMmkW9JMcpXV7VjALVbNU9xfM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8BzLR4=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
Expand Down
43 changes: 36 additions & 7 deletions interp.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,20 +144,24 @@ func (i *Interp) findType(rt reflect.Type, local bool) (types.Type, bool) {
}

func (i *Interp) tryDeferFrame() *frame {
if atomic.LoadInt32(&i.deferCount) != 0 {
if i != nil && atomic.LoadInt32(&i.deferCount) != 0 {
if f, ok := i.deferMap.Load(goroutineID()); ok {
return f.(*frame)
}
}
return &frame{}
}

func (pfn *function) callFunctionByReflect(mtyp reflect.Type, args []reflect.Value, env []interface{}) []reflect.Value {
return pfn.Interp.callFunctionByReflect(pfn.Interp.tryDeferFrame(), mtyp, pfn, args, env)
}

func (i *Interp) FindMethod(mtyp reflect.Type, fn *types.Func) func([]reflect.Value) []reflect.Value {
typ := fn.Type().(*types.Signature).Recv().Type()
if f := i.mainpkg.Prog.LookupMethod(typ, fn.Pkg(), fn.Name()); f != nil {
pfn := i.loadFunction(f)
return func(args []reflect.Value) []reflect.Value {
return i.callFunctionByReflect(i.tryDeferFrame(), mtyp, pfn, args, nil)
return pfn.callFunctionByReflect(mtyp, args, nil)
}
}
name := fn.FullName()
Expand All @@ -174,9 +178,9 @@ func (i *Interp) FindMethod(mtyp reflect.Type, fn *types.Func) func([]reflect.Va
panic(fmt.Sprintf("Not found method %v", fn))
}

func (i *Interp) makeFunction(typ reflect.Type, pfn *function, env []value) reflect.Value {
func (pfn *function) makeFunction(typ reflect.Type, env []value) reflect.Value {
return reflect.MakeFunc(typ, func(args []reflect.Value) []reflect.Value {
return i.callFunctionByReflect(i.tryDeferFrame(), typ, pfn, args, env)
return pfn.Interp.callFunctionByReflect(pfn.Interp.tryDeferFrame(), typ, pfn, args, env)
})
}

Expand Down Expand Up @@ -1129,7 +1133,6 @@ func doRecover(caller *frame) value {
//

func NewInterp(ctx *Context, mainpkg *ssa.Package) (*Interp, error) {
reflectx.Reset()
return newInterp(ctx, mainpkg, nil)
}

Expand Down Expand Up @@ -1298,6 +1301,32 @@ func (i *Interp) RunInit() (err error) {
return
}

// icall allocate stat
func IcallStat() (capacity int, allocate int, aviable int) {
return reflectx.IcallStat()
}

// icall allocate
func (i *Interp) IcallAlloc() int {
return i.record.rctx.IcallAlloc()
}

func (i *Interp) UnsafeReleaseIcall() {
i.record.rctx.Reset()
}

func (i *Interp) UnsafeRelease() {
i.record.Release()
for _, v := range i.funcs {
v.UnsafeRelease()
}
i.funcs = nil
i.msets = nil
i.globals = nil
i.preloadTypes = nil
i.record = nil
}

func (i *Interp) Abort() {
atomic.StoreInt32(&i.exited, 1)
}
Expand Down Expand Up @@ -1325,7 +1354,7 @@ func (i *Interp) GetFunc(key string) (interface{}, bool) {
if !ok {
return nil, false
}
return i.makeFunction(i.toType(fn.Type()), i.funcs[fn], nil).Interface(), true
return i.funcs[fn].makeFunction(i.toType(fn.Type()), nil).Interface(), true
}

func (i *Interp) GetVarAddr(key string) (interface{}, bool) {
Expand Down Expand Up @@ -1402,7 +1431,7 @@ func (i *Interp) GetSymbol(key string) (m ssa.Member, v interface{}, ok bool) {
v, ok = globalToValue(i, p)
case *ssa.Function:
typ := i.toType(p.Type())
v = i.makeFunction(typ, i.funcs[p], nil)
v = i.funcs[p].makeFunction(typ, nil)
case *ssa.Type:
v = i.toType(p.Type())
}
Expand Down
31 changes: 22 additions & 9 deletions opblock.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,20 @@ type function struct {
cached int32 // enable cached by pool
}

func (p *function) UnsafeRelease() {
p.Interp = nil
p.Fn = nil
p.pool = nil
p.index = nil
p.instrIndex = nil
p.Instrs = nil
p.Recover = nil
p.Blocks = nil
p.stack = nil
p.ssaInstrs = nil
p.Main = nil
}

func (p *function) initPool() {
p.pool = &sync.Pool{}
p.pool.New = func() interface{} {
Expand Down Expand Up @@ -217,7 +231,7 @@ func (p *function) regInstr(v ssa.Value) uint32 {
if v.Blocks != nil {
typ := p.Interp.preToType(v.Type())
pfn := p.Interp.loadFunction(v)
vs = p.Interp.makeFunction(typ, pfn, nil).Interface()
vs = pfn.makeFunction(typ, nil).Interface()
} else {
ext, ok := findExternFunc(p.Interp, v)
if !ok {
Expand Down Expand Up @@ -494,7 +508,7 @@ func makeInstr(interp *Interp, pfn *function, instr ssa.Instruction) func(fr *fr
for i := range instr.Bindings {
bindings = append(bindings, fr.reg(ib[i]))
}
v := interp.makeFunction(typ, pfn, bindings)
v := pfn.makeFunction(typ, bindings)
fr.setReg(ir, v.Interface())
}
case *ssa.MakeChan:
Expand Down Expand Up @@ -1155,19 +1169,18 @@ func makeCallInstr(pfn *function, interp *Interp, instr ssa.Value, call *ssa.Cal
}
}

// makeFuncVal sync with Interp.makeFunc
// func (i *Interp) makeFunc(typ reflect.Type, pfn *Function, env []value) reflect.Value {
// makeFuncVal sync with function.makeFunction
// func (pfn *function) makeFunction(typ reflect.Type, env []value) reflect.Value {
// return reflect.MakeFunc(typ, func(args []reflect.Value) []reflect.Value {
// return i.callFunctionByReflect(i.tryDeferFrame(), typ, pfn, args, env)
// return pfn.Interp.callFunctionByReflect(pfn.Interp.tryDeferFrame(), typ, pfn, args, env)
// })
// }

type makeFuncVal struct {
funcval.FuncVal
interp *Interp
typ reflect.Type
pfn *function
env []interface{}
pfn *function
typ reflect.Type
env []interface{}
}

var (
Expand Down
19 changes: 11 additions & 8 deletions runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,18 @@ func init() {
RegisterExternal("runtime.Stack", runtimeStack)
RegisterExternal("runtime/debug.Stack", debugStack)
RegisterExternal("runtime/debug.PrintStack", debugPrintStack)
RegisterExternal("(reflect.Value).Pointer", func(v reflect.Value) uintptr {
if v.Kind() == reflect.Func {
if fv, n := funcval.Get(v.Interface()); n == 1 {
pc := (*makeFuncVal)(unsafe.Pointer(fv)).pfn.base
return uintptr(pc)

if funcval.IsSupport {
RegisterExternal("(reflect.Value).Pointer", func(v reflect.Value) uintptr {
if v.Kind() == reflect.Func {
if fv, n := funcval.Get(v.Interface()); n == 1 {
pc := (*makeFuncVal)(unsafe.Pointer(fv)).pfn.base
return uintptr(pc)
}
}
}
return v.Pointer()
})
return v.Pointer()
})
}
}

func runtimeFuncFileLine(fr *frame, f *runtime.Func, pc uintptr) (file string, line int) {
Expand Down
2 changes: 1 addition & 1 deletion visit.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func (visit *visitor) findLinkFunc(sym *load.LinkSym) (ext reflect.Value, ok boo
}
typ := visit.intp.preToType(sig)
pfn := visit.intp.loadFunction(link)
ext = visit.intp.makeFunction(typ, pfn, nil)
ext = pfn.makeFunction(typ, nil)
ok = true
}
return
Expand Down
22 changes: 17 additions & 5 deletions xtypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ type FindMethod interface {
}

type TypesRecord struct {
rctx *reflectx.Context // reflectx context
loader Loader
finder FindMethod
rcache map[reflect.Type]types.Type
Expand All @@ -180,8 +181,19 @@ type TypesRecord struct {
nstack nestedStack
}

func (r *TypesRecord) Release() {
r.rctx.Reset()
r.loader = nil
r.rcache = nil
r.tcache = nil
r.ncache = nil
r.finder = nil
r.nested = nil
}

func NewTypesRecord(loader Loader, finder FindMethod, nested map[*types.Named]int) *TypesRecord {
return &TypesRecord{
rctx: reflectx.NewContext(),
loader: loader,
finder: finder,
rcache: make(map[reflect.Type]types.Type),
Expand Down Expand Up @@ -297,7 +309,7 @@ func (r *TypesRecord) toInterfaceType(t *types.Interface) (reflect.Type, bool) {
ms[i].PkgPath = pkg.Path()
}
}
return reflectx.InterfaceOf(nil, ms), nested
return r.rctx.InterfaceOf(nil, ms), nested
}

func (r *TypesRecord) toNamedType(t *types.Named) (reflect.Type, bool) {
Expand All @@ -322,7 +334,7 @@ func (r *TypesRecord) toNamedType(t *types.Named) (reflect.Type, bool) {
}
pcount++
}
typ = reflectx.NewMethodSet(typ, mcount, pcount)
typ = r.rctx.NewMethodSet(typ, mcount, pcount)
}
r.saveType(t, typ, nested)
utype, _ := r.ToType(ut)
Expand Down Expand Up @@ -352,7 +364,7 @@ func (r *TypesRecord) toStructType(t *types.Struct) (reflect.Type, bool) {
}
flds[i] = r.toStructField(f, typ, t.Tag(i))
}
typ := reflectx.StructOf(flds)
typ := r.rctx.StructOf(flds)
methods := typeutil.IntuitiveMethodSet(t, nil)
if numMethods := len(methods); numMethods != 0 {
// anonymous structs with methods. struct { T }
Expand All @@ -364,7 +376,7 @@ func (r *TypesRecord) toStructType(t *types.Struct) (reflect.Type, bool) {
}
pcount++
}
typ = reflectx.NewMethodSet(typ, mcount, pcount)
typ = r.rctx.NewMethodSet(typ, mcount, pcount)
r.setMethods(typ, methods)
}
return typ, nested
Expand Down Expand Up @@ -450,7 +462,7 @@ func (r *TypesRecord) setMethods(typ reflect.Type, methods []*types.Selection) {
}
ms = append(ms, reflectx.MakeMethod(fn.Name(), pkgpath, pointer, mtyp, mfn))
}
err := reflectx.SetMethodSet(typ, ms, false)
err := r.rctx.SetMethodSet(typ, ms, false)
if err != nil {
log.Fatalf("SetMethodSet %v err, %v\n", typ, err)
}
Expand Down

0 comments on commit 1d6c597

Please sign in to comment.