compiler: add 'run' command for bytecode interpretation

This commit is contained in:
Ayke van Laethem
2018-09-12 17:26:56 +02:00
parent 8362751590
commit 20c2552f8a
2 changed files with 50 additions and 1 deletions
+3 -1
View File
@@ -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.
+47
View File
@@ -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=<runtime.bc> [-target=<target>] -o <output> <input>\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()