diff --git a/compiler.go b/compiler.go index 9d6bcb39..4e1973e1 100644 --- a/compiler.go +++ b/compiler.go @@ -3026,7 +3026,9 @@ func (c *Compiler) Optimize(optLevel, sizeLevel int, inlinerThreshold uint) { defer builder.Dispose() builder.SetOptLevel(optLevel) builder.SetSizeLevel(sizeLevel) - builder.UseInlinerWithThreshold(inlinerThreshold) + if inlinerThreshold != 0 { + builder.UseInlinerWithThreshold(inlinerThreshold) + } builder.AddCoroutinePassesToExtensionPoints() // Run function passes for each function. diff --git a/main.go b/main.go index e80ca392..40518f07 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "errors" "flag" "fmt" "os" @@ -77,11 +78,42 @@ func Compile(pkgName, runtimePath, outpath, target string, printIR, dumpSSA bool return nil } +// Run the specified package directly (using JIT or interpretation). +func Run(pkgName string) error { + c, err := NewCompiler(pkgName, llvm.DefaultTargetTriple(), false) + if err != nil { + return errors.New("compiler: " + err.Error()) + } + err = c.Parse(pkgName, []string{runtime.GOOS, runtime.GOARCH}) + if err != nil { + return errors.New("compiler: " + err.Error()) + } + if err := c.Verify(); err != nil { + return errors.New("compiler error: failed to verify module: " + err.Error()) + } + c.Optimize(1, 0, 0) // -O1, the fastest optimization level that doesn't crash + + engine, err := llvm.NewExecutionEngine(c.mod) + if err != nil { + return errors.New("interpreter setup: " + err.Error()) + } + defer engine.Dispose() + + main := engine.FindFunction("main") + if main.IsNil() { + return errors.New("could not find main function") + } + engine.RunFunction(main, nil) + + return nil +} + func usage() { fmt.Fprintf(os.Stderr, "usage: %s command [-printir] -runtime= [-target=] -o \n", os.Args[0]) fmt.Fprintln(os.Stderr, "\ncommands:") fmt.Fprintln(os.Stderr, " build: compile packages and dependencies") fmt.Fprintln(os.Stderr, " help: print this help text") + fmt.Fprintln(os.Stderr, " run: run package in an interpreter") fmt.Fprintln(os.Stderr, "\nflags:") flag.PrintDefaults() } @@ -123,6 +155,21 @@ func main() { } case "help": usage() + case "run": + if flag.NArg() != 1 { + fmt.Fprintln(os.Stderr, "No package specified.") + usage() + os.Exit(1) + } + if *target != llvm.DefaultTargetTriple() { + fmt.Fprintf(os.Stderr, "Cannot run %s: target triple does not match host triple.") + os.Exit(1) + } + err := Run(flag.Arg(0)) + if err != nil { + fmt.Fprintln(os.Stderr, "error:", err) + os.Exit(1) + } default: fmt.Fprintln(os.Stderr, "Unknown command:", command) usage()