goplus / igop Goto Github PK
View Code? Open in Web Editor NEWThe Go/Go+ Interpreter
License: Apache License 2.0
The Go/Go+ Interpreter
License: Apache License 2.0
warning, cannot alloc method "atomic.noCopy", cap:256 req:258, import _ "github.com/goplus/reflectx/icall/icall[N]"
SetMethodSet atomic.noCopy err, cannot alloc method "atomic.noCopy", cap:256 req:258
在多线程调用 .RunFunc 发生错误。
fatal error: concurrent map read and map write
goroutine 308 [running]:
github.com/goplus/reflectx.(*provider).Insert(0x2763ab0, 0xc006918700)
github.com/goplus/[email protected]/icall_regabi.go:41 +0x6f
github.com/goplus/reflectx.(*Context).registerMethod(0xc006f44330, 0x1668640?)
github.com/goplus/[email protected]/methodof.go:115 +0xb7
github.com/goplus/reflectx.(*Context).setMethodSet(0xc006f44330, {0x1d9be18, 0xc006918620}, {0xc0084cb180, 0x2, 0x2})
github.com/goplus/[email protected]/methodof.go:272 +0x83b
github.com/goplus/reflectx.(*Context).SetMethodSet(0xc008fb0400?, {0x1d9be18, 0xc006918620}, {0xc0084cb180, 0x2, 0x2}, 0x0)
github.com/goplus/[email protected]/method.go:269 +0x3c5
github.com/goplus/igop.(*TypesRecord).setMethods(0xc005991b00, {0x1d9be18?, 0xc006918620}, {0xc007755050, 0x2, 0x1668600?})
github.com/goplus/[email protected]/xtypes.go:465 +0x459
github.com/goplus/igop.(*TypesRecord).toNamedType(0xc005991b00, 0x1d868c0?)
github.com/goplus/[email protected]/xtypes.go:347 +0x272
github.com/goplus/igop.(*TypesRecord).ToType(0xc005991b00?, {0x1d868c0?, 0xc00b01cbd0?})
github.com/goplus/[email protected]/xtypes.go:264 +0x38b
github.com/goplus/igop.(*TypesRecord).ToType(0x16835e0?, {0x1d868e8?, 0xc004988130?})
github.com/goplus/[email protected]/xtypes.go:242 +0xd8
github.com/goplus/igop.(*Interp).preToType(0xc0027755f0, {0x1d868e8, 0xc004988130})
github.com/goplus/[email protected]/interp.go:1242 +0x5f
github.com/goplus/igop.(*visitor).program(0xc006f44660)
github.com/goplus/[email protected]/visit.go:84 +0x209
github.com/goplus/igop.checkPackages(0xc0027755f0, {0xc0076db4d0, 0x2, 0x4?})
github.com/goplus/[email protected]/visit.go:54 +0x1a6
github.com/goplus/igop.newInterp(0xc0004c6c40, 0xc0040e8c00, 0x0)
github.com/goplus/[email protected]/interp.go:1214 +0x88e
github.com/goplus/igop.NewInterp(...)
github.com/goplus/[email protected]/interp.go:1137
github.com/goplus/igop.(*Context).NewInterp(0x4?, 0xc007f48750?)
github.com/goplus/[email protected]/context.go:587 +0x1b
github.com/goplus/igop.(*Context).RunFunc(0x0?, 0x179c600?, {0x17ccc0b, 0x4}, {0xc003a53418, 0x1, 0x1})
github.com/goplus/[email protected]/context.go:579 +0x32
parser error
bug start of v0.3.10 ~
package main
import "fmt"
var (
test = fmt.Println
)
func main() {
test("hello")
}
$GOROOT/test/chan/select5
bug: golang.org/x/tools/go/ssa build order fp, fc
package main
var c = make(chan int, 1)
var nilch chan int
var n = 1
var x int
var i interface{}
var dummy = make(chan int)
var m = make(map[int]int)
var order = 0
// check order of operations by ensuring that
// successive calls to checkorder have increasing o values.
func checkorder(o int) {
if o <= order {
println("invalid order", o, "after", order)
panic("order")
}
order = o
}
func fc(c chan int, o int) chan int {
checkorder(o)
return c
}
func fp(p *int, o int) *int {
checkorder(o)
return p
}
func init() {
order = 0
c <- n
select {
case *fp(&x, 100) = <-fc(c, 1):
}
if x != n {
die(x)
}
n++
}
func die(x int) {
println("have", x, "want", n)
panic("chan")
}
func main() {
}
func init#1():
0: entry P:0 S:2
*order = 0:int
t0 = *c chan int
t1 = *n int
send t0 <- t1
t2 = fp(x, 100:int) *int
t3 = *c chan int
t4 = fc(t3, 1:int) chan int
t5 = <-t4 int
*t2 = t5
t6 = *x int
t7 = *n int
t8 = t6 != t7 bool
if t8 goto 1 else 2
1: if.then P:1 S:1
t9 = *x int
t10 = die(t9) ()
jump 2
2: if.done P:2 S:0
t11 = *n int
t12 = t11 + 1:int int
*n = t12
return
How to add buildin type/args to interpreter?
panic message
package main
import (
"fmt"
"os"
)
type fileInfoMeta struct {
os.FileInfo
}
func isSymlink(fi os.FileInfo) bool {
return fi != nil && fi.Mode()&os.ModeSymlink == os.ModeSymlink
}
func main() {
fi, err := os.Stat("./main.go")
if err != nil {
panic(err)
}
fmi := &fileInfoMeta{fi}
fmt.Println(isSymlink(fmi))
}
igop run main.go
unexpected type: *reflect.ValueError: reflect: call of reflect.Value.Call on zero Value
x := "hello"
checkString("x", x)
checkString("x[5:]", x[5:])
go:linkname [local] [target]
//go:linkname <localname> <importpath>.<name>
//go:linkname <localname> <importpath>.<type>.<name>
//go:linkname <localname> <importpath>.<(*type)>.<name>
See line 4:
cobra.MinimumNArgs(1)
is cobra.PositionalArgs
cobra.PositionalArgs
cannot use cobra.MinimumNArgs(1) (value of type cobra.PositionalArgs) as cobra.PositionalArgs value in struct literal
// export in https://github.com/fly-studio/docker-compose/blob/v2/igo/pkgs/github.com/spf13/cobra/go118_export.go
import "github.com/spf13/cobra"
rootCmd := &cobra.Command{
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
},
}
modify to below is ok
Args: cobra.PositionalArgs(cobra.MinimumNArgs(1))
Why ?
$GOROOT/test/unsafebuiltins.go
// sliced memory overflows address space
last := (*byte)(unsafe.Pointer(^uintptr(0)))
_ = unsafe.Slice(last, 1)
mustPanic(func() { _ = unsafe.Slice(last, 2) })
https://golang.org/ref/mod#go-mod-vendor
https://go.dev/ref/mod#vendoring
https://go.dev/ref/mod#build-commands
The -mod flag controls whether go.mod may be automatically updated and whether the vendor directory is used.
-mod=mod tells the go command to ignore the vendor directory and to automatically update go.mod, for example, when an imported package is not provided by any known module.
-mod=readonly tells the go command to ignore the vendor directory and to report an error if go.mod needs to be updated.
-mod=vendor tells the go command to use the vendor directory. In this mode, the go command will not use the network or the module cache.
By default, if the go version in go.mod is 1.14 or higher and a vendor directory is present, the go command acts as if -mod=vendor were used. Otherwise, the go command acts as if -mod=readonly were used.
package main
import (
"bytes"
"encoding/binary"
"fmt"
)
func main() {
var buf bytes.Buffer
err := binary.Write(&buf, binary.LittleEndian, int8(1))
fmt.Println(buf, err)
}
igop run main.go
cannot use binary.LittleEndian (variable of type binary.littleEndian) as binary.ByteOrder value in argument to binary.Write: missing method PutUint16 (PutUint16 has pointer receiver)
I just create a simple test project, main.go:
package main
import (
"fmt"
"reflect"
"github.com/goplus/igop"
_ "github.com/goplus/igop/pkg/fmt"
)
var source = `
package notify
type Notify struct {
}
func NewNotify() *Notify {
s := new(Notify)
return s
}
func (s *Notify) Param() (string) {
return "abc"
}
`
type Hello interface {
Param() string
}
func main() {
ctx := igop.NewContext(0)
pkg, err := ctx.LoadFile("hello.go", source)
if err != nil {
fmt.Println(err)
return
}
interp, err := ctx.NewInterp(pkg)
if err != nil {
fmt.Println(err)
return
}
fn, ok := interp.GetFunc("NewNotify")
if !ok {
fmt.Println("error:")
return
}
ret := reflect.ValueOf(fn).Call([]reflect.Value{})
hl := ret[0].Interface().(Hello)
fmt.Println("ret", hl.Param())
}
go.mod:
module hello
go 1.21.4
require github.com/goplus/igop v0.20.0
require (
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
github.com/goplus/reflectx v1.2.1 // indirect
github.com/timandy/routine v1.1.1 // indirect
github.com/visualfc/funcval v0.1.4 // indirect
github.com/visualfc/gid v0.1.0 // indirect
github.com/visualfc/goembed v0.3.2 // indirect
github.com/visualfc/xtype v0.2.0 // indirect
golang.org/x/mod v0.13.0 // indirect
golang.org/x/tools v0.14.0 // indirect
)
It works fine.
But after I run go get -u golang.org/x/tools
,the go.mod updated:
➜ go get -u golang.org/x/tools
go: upgraded golang.org/x/mod v0.13.0 => v0.14.0
go: upgraded golang.org/x/tools v0.14.0 => v0.16.0
➜ cat go.mod
module hello
go 1.21.4
require github.com/goplus/igop v0.20.0
require (
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
github.com/goplus/reflectx v1.2.1 // indirect
github.com/timandy/routine v1.1.1 // indirect
github.com/visualfc/funcval v0.1.4 // indirect
github.com/visualfc/gid v0.1.0 // indirect
github.com/visualfc/goembed v0.3.2 // indirect
github.com/visualfc/xtype v0.2.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/tools v0.16.0 // indirect
)
Then it will panic
➜ go run main.go
panic: runtime error: index out of range [1] with length 1
goroutine 1 [running]:
github.com/goplus/igop.(*Interp).callFunctionByReflect(0x1?, 0xc0000ba8c0, {0xa117e0, 0x8c2520}, 0xc00019e1c0, {0xc000010978, 0x1, 0x2?}, {0x0, 0x0, ...})
/home/super/code/go/pkg/mod/github.com/goplus/[email protected]/interp.go:717 +0x438
github.com/goplus/igop.(*function).callFunctionByReflect(0xc00019e1c0, {0xa117e0, 0x8c2520}, {0xc000010978, 0x1, 0x1}, {0x0, 0x0, 0x0})
/home/super/code/go/pkg/mod/github.com/goplus/[email protected]/interp.go:157 +0xb7
github.com/goplus/igop.(*Interp).FindMethod.func1({0xc000010978?, 0x1?, 0x1?})
/home/super/code/go/pkg/mod/github.com/goplus/[email protected]/interp.go:165 +0x3f
github.com/goplus/reflectx/internal/icall512.i_x(0x0?, 0xc000197d58?, 0xc000197d58?, 0x45ff05?, 0x8dae20?)
/home/super/code/go/pkg/mod/github.com/goplus/[email protected]/internal/icall512/icall_regabi.go:34 +0x68
main.main()
/home/super/code/gocode/tmp/igoptest/main.go:56 +0x1ca
package main
import (
"fmt"
"github.com/goplus/igop"
_ "github.com/goplus/igop/pkg"
)
var src = `package main
import _ "text/template/parse"
func main() {
}
`
func main() {
code, err := igop.RunFile("main.go", src, nil, 0)
fmt.Println(code, err)
}
I'm not sure which directory the path parameter for the AddImport function is relative to. Could you please clarify this for me?
furthermore,if I want to import the current package. How can I do this?
>>> func() { ... }()
https://github.com/goplus/igop/blob/main/cmd/igoptest/main.go
igop run -exp-gc demo.go
func init() {
if runtime.GOARCH == "386" {
gorootTestSkips["printbig.go"] = "load failed"
gorootTestSkips["peano.go"] = "stack overflow"
}
gorootTestSkips["closure.go"] = "runtime.ReadMemStats"
gorootTestSkips["divmod.go"] = "slow, 1m18s"
gorootTestSkips["copy.go"] = "slow, 13s"
gorootTestSkips["finprofiled.go"] = "slow, 21s"
gorootTestSkips["gcgort.go"] = "slow, 2s"
gorootTestSkips["nilptr.go"] = "skip drawin"
gorootTestSkips["heapsampling.go"] = "runtime.MemProfileRecord"
gorootTestSkips["makeslice.go"] = "TODO, panic info, allocation size out of range"
// gorootTestSkips["stackobj.go"] = "skip gc"
// gorootTestSkips["stackobj3.go"] = "skip gc"
gorootTestSkips["nilptr_aix.go"] = "skip"
// gorootTestSkips["init1.go"] = "skip gc"
gorootTestSkips["ken/divconst.go"] = "slow, 3.5s"
gorootTestSkips["ken/modconst.go"] = "slow, 3.3s"
gorootTestSkips["fixedbugs/issue24491b.go"] = "timeout"
gorootTestSkips["fixedbugs/issue16249.go"] = "slow, 4.5s"
gorootTestSkips["fixedbugs/issue13169.go"] = "slow, 5.9s"
gorootTestSkips["fixedbugs/issue11656.go"] = "ignore"
// gorootTestSkips["fixedbugs/issue15281.go"] = "runtime.ReadMemStats"
gorootTestSkips["fixedbugs/issue18149.go"] = "runtime.Caller macos //line not support c:/foo/bar.go:987"
gorootTestSkips["fixedbugs/issue22662.go"] = "runtime.Caller got $goroot/test/fixedbugs/foo.go:1; want foo.go:1"
// gorootTestSkips["fixedbugs/issue27518b.go"] = "BUG, runtime.SetFinalizer"
// gorootTestSkips["fixedbugs/issue32477.go"] = "BUG, runtime.SetFinalizer"
gorootTestSkips["fixedbugs/issue41239.go"] = "BUG, reflect.Append: different capacity on append"
// gorootTestSkips["fixedbugs/issue32477.go"] = "BUG, runtime.SetFinalizer"
gorootTestSkips["fixedbugs/issue45175.go"] = "BUG, ssa.Phi call order"
gorootTestSkips["fixedbugs/issue4618.go"] = "testing.AllocsPerRun"
gorootTestSkips["fixedbugs/issue4667.go"] = "testing.AllocsPerRun"
gorootTestSkips["fixedbugs/issue8606b.go"] = "BUG, optimization check"
gorootTestSkips["fixedbugs/issue30116u.go"] = "BUG, slice bound check"
gorootTestSkips["chan/select5.go"] = "bug, select case expr call order"
// fixedbugs/issue7740.go
// const ulp = (1.0 + (2.0 / 3.0)) - (5.0 / 3.0)
// Go 1.14 1.15 1.16 ulp = 1.4916681462400413e-154
// Go 1.17 1.18 ulp = 0
ver := runtime.Version()[:6]
switch ver {
case "go1.17", "go1.18", "go1.19", "go1.20":
// gorootTestSkips["fixedbugs/issue45045.go"] = "runtime.SetFinalizer"
// gorootTestSkips["fixedbugs/issue46725.go"] = "runtime.SetFinalizer"
gorootTestSkips["abi/fibish.go"] = "slow, 34s"
gorootTestSkips["abi/fibish_closure.go"] = "slow, 35s"
gorootTestSkips["abi/uglyfib.go"] = "5m48s"
// gorootTestSkips["fixedbugs/issue23017.go"] = "BUG" //fixed https://github.com/golang/go/issues/55086
gorootTestSkips["typeparam/chans.go"] = "runtime.SetFinalizer, maybe broken for go1.18 on linux workflows"
// gorootTestSkips["typeparam/issue376214.go"] = "build SSA package error: variadic parameter must be of unnamed slice type"
if ver != "go1.20" {
gorootTestSkips["typeparam/nested.go"] = "skip, run pass but output same as go1.20"
}
//go1.20
gorootTestSkips["fixedbugs/bug514.go"] = "skip cgo"
gorootTestSkips["fixedbugs/issue40954.go"] = "skip cgo"
gorootTestSkips["fixedbugs/issue42032.go"] = "skip cgo"
gorootTestSkips["fixedbugs/issue42076.go"] = "skip cgo"
gorootTestSkips["fixedbugs/issue46903.go"] = "skip cgo"
gorootTestSkips["fixedbugs/issue51733.go"] = "skip cgo"
// gorootTestSkips["fixedbugs/issue57823.go"] = "GC"
case "go1.16":
gorootTestSkips["fixedbugs/issue7740.go"] = "BUG, const float"
case "go1.15":
gorootTestSkips["fixedbugs/issue15039.go"] = "BUG, uint64 -> string"
gorootTestSkips["fixedbugs/issue9355.go"] = "TODO, chdir"
gorootTestSkips["fixedbugs/issue7740.go"] = "BUG, const float"
case "go1.14":
gorootTestSkips["fixedbugs/issue9355.go"] = "TODO, chdir"
gorootTestSkips["fixedbugs/issue7740.go"] = "BUG, const float"
}
if runtime.GOOS == "windows" {
gorootTestSkips["env.go"] = "skip GOARCH"
gorootTestSkips["fixedbugs/issue15002.go"] = "skip windows"
gorootTestSkips["fixedbugs/issue5493.go"] = "skip windows"
gorootTestSkips["fixedbugs/issue5963.go"] = "skip windows"
skips := make(map[string]string)
for k, v := range gorootTestSkips {
skips[filepath.FromSlash(k)] = v
}
gorootTestSkips = skips
} else if runtime.GOOS == "darwin" {
gorootTestSkips["locklinear.go"] = "skip github"
}
}
package main
import (
"fmt"
)
func main() {
type P struct{ i int }
var m = map[int]int{}
var p *P
defer func() {
recover()
check(1, len(m))
check(3, m[2])
}()
m[2], p.i = 3, 2
}
func check(want, got int) {
if want != got {
panic(fmt.Sprintf("wanted %d, but got %d", want, got))
}
}
- io_extra/
- file.go
- main.go
how to import io_extra/file.go in main.go?
import "io_extra"
panic:
could not import io_extra (not found provider for types.Importer)
我的意思是编译成二进制之后,无法引用。虽然有 Context.External,但不知道如何实现。
reflect call method frame args not pass.
Now:
mContext := igop.NewContext(0)
pkg, err := mContext.LoadDir("./go/item", false)
if err != nil {
panic(err)
}
mInterp, _ := mContext.NewInterp(pkg)
r, err := mInterp.RunFunc("NewStructure", nil)
if err != nil {
panic(err)
}
Want:
mContext := igop.NewContext(0)
pkg, err := mContext.LoadDir("./go", false)
if err != nil {
panic(err)
}
mInterp, _ := mContext.NewInterp(pkg)
r, err := mInterp.RunFunc("item.NewStructure", nil)
if err != nil {
panic(err)
}
like exec/cmd cmd := exec.CommandContext(...) cmd.Env = ....
env := map[string]string{"X": "Y"}
ctx := igop.NewContext(0)
ctx.Env = env
ctx.Run(....)
Title.
must merge test and xtest to one test pkg.
demo
package main
import (
"go/token"
)
type CFG struct {
}
func (g *CFG) Format(fset *token.FileSet) {
}
func main() {
}
no concrete method: func (*sync/atomic.Pointer[go/token.File]).CompareAndSwap(*go/token.File, *go/token.File) bool
When the filename of the package dependency introduced by a third-party package contains "_", it prompts "no buildable Go source file in".
.go file //go:build sep // +build sep
igop export -addtags sep -outdir pkg packagepath
errors:
undeclared name: SetVersion
Menu not declared by package call
undeclared name: xxxxx
dir1/flie.go=package a xxxxx
dir2/file.go = package b import a xxxxxxx
igop 0.9.1
\load\embed_go116.go:94:29: not enough arguments in call to r.Load
r.Load(bp.Dir, v)
\go\pkg\mod\github.com\visualfc\[email protected]\resolve.go
Load(dir string, fset *token.FileSet, em *Embed) ([]*File, error)
include test files
igop run ( not load test file)
igop test ( include test file)
support -tags
igop run -tags
igop test -tags
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.