Skip to content

Instantly share code, notes, and snippets.

@mrnugget
Created September 22, 2018 05:23
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrnugget/891078a2f02d909d107d7cc8469ddd98 to your computer and use it in GitHub Desktop.
Save mrnugget/891078a2f02d909d107d7cc8469ddd98 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"plugin"
"github.com/pkg/errors"
)
var contents = `
package main
func AddTwo(i int) int {
return i + 2
}
`
var compileTmpDir = "./jit_tmp"
func jitCompile(name, goCode string) (string, error) {
tmpFile := filepath.Join(compileTmpDir, name+".go")
pluginFile := filepath.Join(compileTmpDir, name+".go.so")
err := ioutil.WriteFile(tmpFile, []byte(goCode), 0644)
if err != nil {
return "", errors.Wrap(err, "could not create tmpfile")
}
defer os.Remove(tmpFile)
cmd := exec.Command("go", "build", "-o", pluginFile, "-buildmode=plugin", tmpFile)
err = cmd.Start()
if err != nil {
return "", errors.Wrap(err, "go build could not be started")
}
err = cmd.Wait()
if err != nil {
return "", errors.Wrap(err, "go build failed")
}
return pluginFile, nil
}
func main() {
pluginPath, err := jitCompile("add_two", contents)
if err != nil {
fmt.Printf("jit compilation failed: %s\n", err)
os.Exit(1)
}
defer os.Remove(pluginPath)
plug, err := plugin.Open(pluginPath)
if err != nil {
fmt.Println(err)
return
}
addTwoSymbol, err := plug.Lookup("AddTwo")
if err != nil {
fmt.Println(err)
return
}
jittedAddTwo, ok := addTwoSymbol.(func(int) int)
if !ok {
fmt.Println("addTwoSymbol has wrong type")
return
}
result := jittedAddTwo(2)
fmt.Printf("result=%d\n", result)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment