GoLightly is a flexible library for building virtual machines in Go. Instead of a single general purpose VM it encourages the use of many small, specialised VMs working in concert.
3. a new language
statically-typed and compiled
object-oriented but no classes
garbage collected
concurrency via communication (CSP)
type polymorphism via interfaces
4. a new way of working
the safety of a static type system
the feel of a dynamic runtime
the performance of a compiled language
14. bytecode
type ByteCode []int case 5: / JMPZ n
/ case 10: / POP r
/
func (b *ByteCode) String() string { PC++ PC++
return "BYTECODE" if C == 0 { R[b[PC]] = DS.Pop()
} PC++ case 11: / LOAD r, v
/
func (b *ByteCode) Execute(p Processor) { PC += b[PC] - 1 PC++
var PC, C, W int } else { W = b[PC]
var R [2]int PC++ PC++
CS := new(vector.IntVector) } R[W] = b[PC]
DS := new(vector.IntVector) case 6: / JMPNZ n
/ case 12: / ADD r1, r2
/
for p.Active() { PC++ PC++
switch b[PC] { if C != 0 { W = b[PC]
case 0: / NOOP
/ PC++ PC++
case 1: / NSLEEP n
/ PC += b[PC] - 1 R[b[PC]] += R[W]
PC++ } else { default:
p.Sleep(int64(b[PC])) PC++ p.Halt(ILLEGAL_INSTRUCTION)
case 2: / SLEEP n
/ } }
PC++ case 7: / CALL n
/ }
p.Sleep(int64(b[PC]) << 32) PC++ }
case 3: / HALT
/ CS.Push(PC)
p.Halt(USER_HALT) PC = b[PC]
return case 8: / RET
/
case 4: / JMP n
/ PC = CS.Pop
PC++ case 9: / PUSH r
/
PC += b[PC] - 1 PC++
DS.Push(R[b[PC]])
16. a scalar processor
type SProc struct { func (s *SProc) Sleep(i int64) { func (s *SProc) Call(a Address){
Running bool syscall.Sleep(i) PC := s.PC
PC int } s.PC = int(a)
R IntBuffer for s.IsActive() {
F FloatBuffer func (s *SProc) Halt(n int) { s.Execute()
DS vector.IntVector s.Running = false s.Step()
Program []Executable } }
} s.PC = PC
func (s *SProc) IsActive() bool{ }
func (s *SProc) Run() { return s.Running && s.PC <
s.Running = true len(s.Program) func (s *SProc) Return() {
s.Call(0) } s.PC = len(s.Program)
} }
func (s *SProc) Reset() {
func (s *SProc) Step() { s.R.ClearAll()
s.PC++ s.PC = 0
} }
func (s *SProc) Jump(a Address) { func (s *SProc) Load(program
s.PC += int(a) Program) {
} s.Reset()
s.Program = program
func (s *SProc) Execute() { }
s.Program[s.PC].Execute(s)
}
17. memory
based on allocated Values
aggregate as ValueStores
require boxing/unboxing
buffers for speciïŹc types
buffers are also ValueStores
18. beneïŹts
encourages simple designs
many different VMs per executable
can run in separate goroutines
easily duplicated and serialised
split across processes or hosts
19. the future
single dispatch for vector operations
per vasive threading
runtime code rewriting
speculative loading
JIT compilation