Skip to content

Commit

Permalink
js/modules: refactor set/runMain into RunSourceData
Browse files Browse the repository at this point in the history
  • Loading branch information
mstoykov committed May 26, 2023
1 parent 2f94491 commit 51ee021
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 28 deletions.
5 changes: 1 addition & 4 deletions js/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,6 @@ func newBundle(
c := bundle.newCompiler(piState.Logger)
bundle.ModuleResolver = modules.NewModuleResolver(getJSModules(), generateFileLoad(bundle), c)

if err = bundle.ModuleResolver.SetMain(src, c); err != nil {
return nil, err
}
// Instantiate the bundle into a new VM using a bound init context. This uses a context with a
// runtime, but no state, to allow module-provided types to function within the init context.
// TODO use a real context
Expand Down Expand Up @@ -288,7 +285,7 @@ func (b *Bundle) instantiate(vuImpl *moduleVUImpl, vuID uint64) (*goja.Object, e
return vuImpl.eventLoop.Start(func() error {
//nolint:shadow,govet // here we shadow err on purpose
var err error
exportsV, err = modSys.RunMain()
exportsV, err = modSys.RunSourceData(b.sourceData)
return err
})
})
Expand Down
48 changes: 24 additions & 24 deletions js/modules/resolution.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ type ModuleResolver struct {
goModules map[string]interface{}
loadCJS FileLoader
compiler *compiler.Compiler

// TODO: figure out a way to not have to have this
mainpwd *url.URL
mainSpecifier string
}

// NewModuleResolver returns a new module resolution instance that will resolve.
Expand All @@ -50,16 +46,6 @@ func NewModuleResolver(goModules map[string]interface{}, loadCJS FileLoader, c *
}
}

// SetMain sets what is the main module/script for this resolver
// TODO: this likely will change with ESM support
func (mr *ModuleResolver) SetMain(main *loader.SourceData, c *compiler.Compiler) error {
mr.mainSpecifier = main.URL.String()
mr.mainpwd = main.URL.ResolveReference(&url.URL{Path: "../"}) // TODO: fix
mod, err := cjsModuleFromString(main.URL, main.Data, c)
mr.cache[main.URL.String()] = moduleCacheElement{mod: mod, err: err}
return err
}

func (mr *ModuleResolver) resolveSpecifier(basePWD *url.URL, arg string) (*url.URL, error) {
specifier, err := loader.Resolve(basePWD, arg)
if err != nil {
Expand All @@ -80,6 +66,21 @@ func (mr *ModuleResolver) requireModule(name string) (module, error) {
return &baseGoModule{mod: mod}, nil
}

func (mr *ModuleResolver) resolveLoaded(basePWD *url.URL, arg string, data []byte) (module, error) {
specifier, err := mr.resolveSpecifier(basePWD, arg)
if err != nil {
return nil, err
}
// try cache with the final specifier
if cached, ok := mr.cache[specifier.String()]; ok {
return cached.mod, cached.err
}

mod, err := cjsModuleFromString(specifier, data, mr.compiler)
mr.cache[specifier.String()] = moduleCacheElement{mod: mod, err: err}
return mod, err
}

func (mr *ModuleResolver) resolve(basePWD *url.URL, arg string) (module, error) {
if cached, ok := mr.cache[arg]; ok {
return cached.mod, cached.err
Expand Down Expand Up @@ -149,18 +150,17 @@ func (ms *ModuleSystem) Require(pwd *url.URL, arg string) (*goja.Object, error)
return instance.exports(), nil
}

// RunMain runs the main module and returns it exports
// RunSourceData runs the provided sourceData and adds it to the cache.
// If a module with the same specifier as the source is already cached
// it will be used instead of reevaluating the source from the provided SourceData.
//
// TODO: this API will likely change as native ESM support will likely not let us have the exports
// as one big goja.Value that we can manipulate
func (ms *ModuleSystem) RunMain() (goja.Value, error) {
mod, err := ms.resolver.resolve(ms.resolver.mainpwd, ms.resolver.mainSpecifier)
if err != nil {
func (ms *ModuleSystem) RunSourceData(source *loader.SourceData) (goja.Value, error) {
specifier := source.URL.String()
pwd := source.URL.JoinPath("../")
if _, err := ms.resolver.resolveLoaded(pwd, specifier, source.Data); err != nil {
return nil, err // TODO wrap as this should never happen
}
instance := mod.instantiate(ms.vu)
err = instance.execute()
if err != nil {
return nil, err
}
return instance.exports(), err
return ms.Require(pwd, specifier)
}

0 comments on commit 51ee021

Please sign in to comment.