diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1459a384..d77b54d0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ jobs: name: Test with ${{ matrix.go-version }} on ${{ matrix.vm-os }} runs-on: ${{ matrix.vm-os }} env: - CI_REPORT: ${{ matrix.vm-os == 'ubuntu-20.04' && matrix.go-version == '1.18.10' }} + CI_REPORT: ${{ matrix.vm-os == 'ubuntu-20.04' && startsWith(matrix.go-version, '1.18.') }} strategy: max-parallel: 10 fail-fast: false diff --git a/cache.go b/cache.go index 306448da..869ee5a4 100644 --- a/cache.go +++ b/cache.go @@ -8,6 +8,7 @@ import ( "unsafe" "go.starlark.net/starlark" + "go.starlark.net/syntax" ) // The following code is copied and modified from the starlark-go repo, @@ -23,6 +24,7 @@ type cache struct { cacheMu sync.Mutex cache map[string]*entry globals starlark.StringDict + execOpts *syntax.FileOptions loadMod func(s string) (starlark.StringDict, error) // load from built-in module first readFile func(s string) ([]byte, error) // and then from file system } @@ -108,7 +110,12 @@ func (c *cache) doLoad(cc *cycleChecker, module string) (starlark.StringDict, er if err != nil { return nil, err } - return starlark.ExecFile(thread, module, b, c.globals) + + // 3. execute the source file + if c.execOpts == nil { + return starlark.ExecFile(thread, module, b, c.globals) + } + return starlark.ExecFileOptions(c.execOpts, thread, module, b, c.globals) } // -- concurrent cycle checking -- diff --git a/run.go b/run.go index e5d9ef62..05fe64d7 100644 --- a/run.go +++ b/run.go @@ -241,8 +241,9 @@ func (m *Machine) prepareThread(extras StringAnyMap) (err error) { // cache load&read + printf -> thread m.loadCache = &cache{ - cache: make(map[string]*entry), - loadMod: m.lazyloadMods.GetLazyLoader(), + cache: make(map[string]*entry), + execOpts: m.getFileOptions(), + loadMod: m.lazyloadMods.GetLazyLoader(), readFile: func(name string) ([]byte, error) { return readScriptFile(name, m.scriptFS) }, diff --git a/run_test.go b/run_test.go index 8c4a5add..f9493ef4 100644 --- a/run_test.go +++ b/run_test.go @@ -701,6 +701,44 @@ x = fib(10) expectErr(t, err, `starlark: exec: function fib called recursively`) } +func Test_Machine_Run_RecursionLoad(t *testing.T) { + code := ` +load("fibonacci2.star", "fib") +x = fib(10) +` + { + // create machine + m := starlet.NewDefault() + // set code + m.SetScript("ans.star", []byte(code), os.DirFS("testdata")) + // run + _, err := m.Run() + if err == nil { + t.Errorf("expected error, got nil") + return + } + } + + { + // create machine + m := starlet.NewDefault() + m.EnableRecursionSupport() + // set code + m.SetScript("ans.star", []byte(code), os.DirFS("testdata")) + // run + out, err := m.Run() + if err != nil { + t.Errorf("unexpected error: %v", err) + } + // check result + if out == nil { + t.Errorf("unexpected nil output") + } else if out["x"] != int64(55) { + t.Errorf("unexpected output: %v", out) + } + } +} + func Test_Machine_Run_LoadErrors(t *testing.T) { mm := starlark.NewDict(1) _ = mm.SetKey(starlark.String("quarter"), starlark.MakeInt(100)) diff --git a/testdata/fibonacci2.star b/testdata/fibonacci2.star new file mode 100644 index 00000000..10099d9a --- /dev/null +++ b/testdata/fibonacci2.star @@ -0,0 +1,4 @@ +def fib(n): + if n < 2: + return n + return fib(n - 1) + fib(n - 2)