compiler: add 'run' command for bytecode interpretation

Этот коммит содержится в:
Ayke van Laethem 2018-09-12 17:26:56 +02:00
родитель 8362751590
коммит 20c2552f8a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: E97FF5335DFDFDED
2 изменённых файлов: 50 добавлений и 1 удалений

Просмотреть файл

@ -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
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=<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()