func newForeign(vm *C.WrenVM, x interface{}) {
	var (
		v   = reflect.Indirect(reflect.ValueOf(x))
		t   = v.Type()
		ptr = C.wrenSetSlotNewForeign(vm, C.int(0), C.int(0), C.size_t(t.Size()))
	)
	reflect.NewAt(t, ptr).Elem().Set(v)
}
newForeign allocates a new foreign object.

This method should only be called from a foreign class allocation function.
It takes an instance of the VM and a newly allocated foreign object ("foreign"
meaning that it's created in Go and not Wren) and makes it available to Wren.
package wren
import "C"
import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"runtime"
	"strings"
	"unsafe"
)
var (
	vmMap     = make(map[*C.WrenVM]*VM)
	errWriter io.Writer
)
type VM struct {
	vm               *C.WrenVM
	classes, methods map[string]unsafe.Pointer
	userData         map[string]interface{}
	userDataPtr      unsafe.Pointer
	outWriter        io.Writer
}
func NewVM() *VM {
	var config C.WrenConfiguration
	C.wrenInitConfiguration(&config)
	config.writeFn = C.WrenWriteFn(C.write)
	config.bindForeignMethodFn = C.WrenBindForeignMethodFn(C.bindMethod)
	config.bindForeignClassFn = C.WrenBindForeignClassFn(C.bindClass)
	config.errorFn = C.WrenErrorFn(C.writeErr)
	config.loadModuleFn = C.WrenLoadModuleFn(C.loadModule)
	vm := VM{vm: C.wrenNewVM(&config)}
	vm.classes = make(map[string]unsafe.Pointer)
	vm.methods = make(map[string]unsafe.Pointer)
	vm.userData = make(map[string]interface{})
	vmMap[vm.vm] = &vm
	runtime.SetFinalizer(&vm, func(vm *VM) {
		C.wrenFreeVM(vm.vm)
		delete(vmMap, vm.vm)
	})
	return &vm
}
func (vm *VM) SetModulesDir(path string) {
	vm.setUserData("MODULES_DIR", path)
}
func (vm *VM) setUserData(key string, val interface{}) {
	vm.userData[key] = val
	if jval, e := json.Marshal(vm.userData); e == nil {
		if vm.userDataPtr != nil {
			C.free(vm.userDataPtr)
		}
		vm.userDataPtr = unsafe.Pointer(C.CString(string(jval)))
		C.wrenSetUserData(vm.vm, vm.userDataPtr)
	}
}
func (vm *VM) RegisterForeignMethod(fullName string, f interface{}) error {
	ptr, err := registerFunc(fullName, func() {
		if err := handleFunction(vm.vm, f); err != nil {
			panic(err)
		}
	})
	if err != nil {
		return err
	}
	vmMap[vm.vm].methods[fullName] = ptr
	return nil
}
func (vm *VM) RegisterForeignClass(className string, f func() interface{}) error {
	ptr, err := registerFunc(className, func() {
		newForeign(vm.vm, f())
	})
	if err != nil {
		return err
	}
	vmMap[vm.vm].classes[className] = ptr
	return nil
}
func (vm *VM) SetOutputWriter(w io.Writer) {
	vmMap[vm.vm].outWriter = w
}
func SetErrorWriter(w io.Writer) {
	errWriter = w
}
func (vm *VM) GC() {
	C.wrenCollectGarbage(vm.vm)
}
func (vm *VM) Interpret(source string) error {
	c_module := C.CString("main")
	defer C.free(unsafe.Pointer(c_module))
	c_source := C.CString(source)
	defer C.free(unsafe.Pointer(c_source))
	return interpretResultToErr(C.wrenInterpret(vm.vm, c_module, c_source))
}
func (vm *VM) InterpretFile(filename string) error {
	contents, err := ioutil.ReadFile(filename)
	if err != nil {
		return err
	}
	return vm.Interpret(string(contents))
}
func (vm *VM) InterpretReader(r io.Reader) error {
	contents, err := ioutil.ReadAll(r)
	if err != nil {
		return err
	}
	return vm.Interpret(string(contents))
}
func (vm *VM) getVariable(module, name string, slot int) {
	var (
		c_module = C.CString(module)
		c_name   = C.CString(name)
	)
	defer func() {
		C.free(unsafe.Pointer(c_module))
		C.free(unsafe.Pointer(c_name))
	}()
	C.wrenGetVariable(vm.vm, c_module, c_name, C.int(slot))
}
type Value struct {
	vm      *C.WrenVM
	value   *C.WrenHandle
	methods map[string]*C.WrenHandle
}
func (vm *VM) Variable(name string) *Value {
	var (
		c_module = C.CString("main")
		c_name   = C.CString(name)
	)
	defer func() {
		C.free(unsafe.Pointer(c_module))
		C.free(unsafe.Pointer(c_name))
	}()
	C.wrenEnsureSlots(vm.vm, 1)
	C.wrenGetVariable(vm.vm, c_module, c_name, 0)
	value := Value{vm: vm.vm, value: C.wrenGetSlotHandle(vm.vm, 0)}
	if value.value == nil {
		return nil
	}
	value.methods = make(map[string]*C.WrenHandle)
	runtime.SetFinalizer(&value, func(value *Value) {
		for _, method := range value.methods {
			C.wrenReleaseHandle(vm.vm, method)
		}
		C.wrenReleaseHandle(vm.vm, value.value)
	})
	return &value
}
func (v *Value) Call(signature string, params ...interface{}) (interface{}, error) {
	f := v.methods[signature]
	if f == nil {
		c_signature := C.CString(signature)
		defer C.free(unsafe.Pointer(c_signature))
		f = C.wrenMakeCallHandle(v.vm, c_signature)
		v.methods[signature] = f
	}
	C.wrenEnsureSlots(v.vm, C.int(len(params)+1))
	C.wrenSetSlotHandle(v.vm, 0, v.value)
	for i, param := range params {
		saveToSlot(v.vm, i+1, reflect.ValueOf(param))
	}
	if err := interpretResultToErr(C.wrenCall(v.vm, f)); err != nil {
		return nil, err
	}
	if retval := getFromSlot(v.vm, 0, nil); retval.IsValid() {
		return retval.Interface(), nil
	}
	return nil, nil
}