Git Product home page Git Product logo

igop's Issues

fatal error: concurrent map read and map write

在多线程调用 .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

bug: var fn is nil

bug start of v0.3.10 ~

package main

import "fmt"

var (
	test = fmt.Println
)

func main() {
	test("hello")
}

bug: ssa select case call expr order

$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

unexpected type: *reflect.ValueError: reflect: call of reflect.Value.Call on zero Value

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

support go:linkname

go:linkname [local] [target]

//go:linkname <localname> <importpath>.<name>
//go:linkname <localname> <importpath>.<type>.<name>
//go:linkname <localname> <importpath>.<(*type)>.<name>

Function pointer type support is incomplete

See line 4:

  • the return type of cobra.MinimumNArgs(1) is cobra.PositionalArgs
  • but you must cast the return to cobra.PositionalArgs
  • otherwise, report error: 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 ?

unsafe.Slice for go1.18

$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) })

vendor support

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.

bug binary.LittleEndian

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)

simple program panic with golang.org/x/tools new version

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

parse.stateFn circle

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)
}

about function "importdir"

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?

TODO: $GOROOT/test/fixedbugs

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"
	}
}

bug: golang fixedbugs/issue23017.go

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))
	}
}

support feature like Interp.RunFunc("fmt.Println")

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)
}

no concrete method for token.File

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

speed up qexp

  • qexp use golang.org/x/tools/go/loader is very slow
  • support qexp pkg/...
  • igop export pkg

0.9.1 version cannot be compiled

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)

igop run & test files

  • include test files
    igop run ( not load test file)
    igop test ( include test file)

  • support -tags
    igop run -tags
    igop test -tags

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.