Skip to content

Instantly share code, notes, and snippets.

@mtornwall
Created July 17, 2013 14:10
Show Gist options
  • Save mtornwall/6020868 to your computer and use it in GitHub Desktop.
Save mtornwall/6020868 to your computer and use it in GitHub Desktop.
derpy derp jit for basic arithmetic in Go
package main
// int callGate(void* p) {
// return ((int (*)())p)();
// }
import "C"
import (
"os"
"io"
"fmt"
"syscall"
"unsafe"
"bytes"
"bufio"
"unicode"
)
type Compiler struct {
Buffer *bytes.Buffer
Reader *bufio.Reader
Curr rune
}
func NewCompiler(in io.Reader) *Compiler {
c := &Compiler{
Buffer: bytes.NewBuffer([]byte{}),
Reader: bufio.NewReader(in),
}
c.Next()
return c
}
func (c *Compiler) Program() {
//c.Buffer.WriteByte(0xcc) // INT3 debugger break
c.Expression()
fmt.Printf("retq\n")
c.Buffer.WriteByte(0xc3)
}
func (c *Compiler) Expression() {
c.Number()
if c.Curr == '+' {
fmt.Printf("push\t%%rax\n")
c.Buffer.WriteByte(0x50)
c.Next()
c.Expression()
fmt.Printf("pop\t%%rdi\n")
c.Buffer.WriteByte(0x5f)
fmt.Printf("add\t%%rdi,%%rax\n")
c.Buffer.Write([]byte{0x48, 0x01, 0xf8})
}
}
func (c *Compiler) Number() {
var sum int32 = 0
for unicode.IsDigit(c.Curr) {
sum = sum*10 + int32(c.Curr)-'0'
c.Next()
}
fmt.Printf("mov\t$%d,%%rax\n", sum)
c.Buffer.Write([]byte{0x48, 0xc7, 0xc0})
c.Buffer.Write([]byte{
byte(sum & 0xff),
byte((sum >> 8) & 0xff),
byte((sum >> 16) & 0xff),
byte(sum >> 24)})
}
func (c *Compiler) Next() {
r, _, err := c.Reader.ReadRune()
if err != nil {
panic("Error reading next character")
}
c.Curr = r
}
func main() {
data, err := syscall.Mmap(-1, 0, 4096, syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC, syscall.MAP_PRIVATE|syscall.MAP_ANONYMOUS)
if err != nil {
fmt.Printf("Error: mmap: %s\n", err);
}
c := NewCompiler(os.Stdin)
c.Program()
copy(data, c.Buffer.Bytes())
rv := C.callGate(unsafe.Pointer(&data[0]))
fmt.Printf("==> %d\n", rv)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment