This commit is contained in:
Cadey Ratio 2018-08-06 18:04:11 -07:00
parent 3932cd5f07
commit 15481872dd
2 changed files with 137 additions and 0 deletions

134
cmd/land/go.go Normal file
View File

@ -0,0 +1,134 @@
package main
import (
"bytes"
"crypto/rand"
"encoding/binary"
"os"
"time"
)
func (p *Process) getInt32(addr int32) int32 {
mem := p.vm.Memory()[addr : addr+4]
var result int32
err := binary.Read(bytes.NewReader(mem), binary.LittleEndian, &result)
if err != nil {
panic(err)
}
return result
}
func (p *Process) setInt32(addr int32, val int32) {
data := make([]byte, 4)
buf := bytes.NewBuffer(data)
err := binary.Write(buf, binary.LittleEndian, val)
if err != nil {
panic(err)
}
_, err := p.writeMem(addr, data)
if err != nil {
panic(err)
}
}
func (p *Process) getInt64(addr int32) int64 {
mem := p.vm.Memory()[addr : addr+8]
var result int64
err := binary.Read(bytes.NewReader(mem), binary.LittleEndian, &result)
if err != nil {
panic(err)
}
return result
}
func (p *Process) setInt64(addr int32, val int64) {
data := make([]byte, 8)
buf := bytes.NewBuffer(data)
err := binary.Write(buf, binary.LittleEndian, val)
if err != nil {
panic(err)
}
_, err := p.writeMem(addr, data)
if err != nil {
panic(err)
}
}
// goRuntimeWasmExit implements the go runtime function runtime.wasmExit. It uses
// the Go abi.
//
// This has the effective type of:
//
// func (p *Process) goRuntimeWasmExit(code int32)
func (p *Process) goRuntimeWasmExit(sp int32) {
exitCode := p.getInt32(sp + 8)
os.Exit(int(exitCode))
}
// goRuntimeWasmWrite wraps the write function.
//
// This has the effective type of:
//
// func (p *Process) goRuntimeWasmWrite(fd int64, ptr int64, n int32)
func (p *Process) goRuntimeWasmWrite(sp int32) {
fd := p.getInt64(sp + 8)
ptr := p.getInt64(sp + 16)
n := p.getInt32(sp + 24)
result := p.write(int32(fd), int32(ptr), n)
// TODO: write result to wasmWrite?
_ = result
}
// goRuntimeNanotime implements the go runtime function runtime.nanotime. It uses
// the Go abi.
//
// This has the effective type of:
//
// func (p *Process) goRuntimeNanotime() int64
func (p *Process) goRuntimeNanotime(sp int32) {
p.setInt64(sp+8, int64(time.Now().UnixNano()))
}
// goRuntimeWalltime implements the go runtime function runtime.walltime. It uses
// the Go abi.
//
// This has the effective type of:
//
// func (p *Process) goRuntimeWalltime() (int64, int32)
func (p *Process) goRuntimeWalltime(sp int32) {
now := time.Now()
p.setInt64(sp+8, now.Unix())
p.setInt32(sp+16, int32(now.Nanosecond()))
}
// goRuntimeScheduleCallback implements the go runtime function runtime.scheduleCallback.
// It uses the Go abi and is not implemented yet.
func (p *Process) goRuntimeScheduleCallback(sp int32) {
p.setInt32(sp+16, -1)
}
func (p *Process) goRuntimeClearScheduledCallback(sp int32) {}
// goLoadSlice loads a Go slice out of wasm memory. It uses the the Go abi.
func (p *Process) goLoadSlice(sp int32) []byte {
arr := p.getInt64(sp)
len := p.getInt64(sp + 8)
return p.vm.Memory()[arr : arr+len]
}
func (p *Process) goRuntimeGetRandomData(sp int32) {
data := p.goLoadSlice(sp + 8)
_, err := rand.Read(data)
if err != nil {
panic(err)
}
p.writeMem(sp+8, data)
}

View File

@ -25,6 +25,9 @@ type Process struct {
fs afero.Fs
files []afero.File
name string
// go runtime cruft
goRuntimeValues []interface{}
}
// NewProcess constructs a new webassembly process based on the input webassembly module as a reader.