compiler: add 'run' command for bytecode interpretation
Этот коммит содержится в:
родитель
8362751590
коммит
20c2552f8a
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
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()
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче