This commit is contained in:
parent
3932cd5f07
commit
15481872dd
|
@ -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)
|
||||||
|
}
|
|
@ -25,6 +25,9 @@ type Process struct {
|
||||||
fs afero.Fs
|
fs afero.Fs
|
||||||
files []afero.File
|
files []afero.File
|
||||||
name string
|
name string
|
||||||
|
|
||||||
|
// go runtime cruft
|
||||||
|
goRuntimeValues []interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewProcess constructs a new webassembly process based on the input webassembly module as a reader.
|
// NewProcess constructs a new webassembly process based on the input webassembly module as a reader.
|
||||||
|
|
Loading…
Reference in New Issue