// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package eval import "os" /* * Virtual machine */ type Thread struct { abort chan os.Error pc uint // The execution frame of this function. This remains the // same throughout a function invocation. f *Frame } type code []func(*Thread) func (i code) exec(t *Thread) { opc := t.pc t.pc = 0 l := uint(len(i)) for t.pc < l { pc := t.pc t.pc++ i[pc](t) } t.pc = opc } /* * Code buffer */ type codeBuf struct { instrs code } func newCodeBuf() *codeBuf { return &codeBuf{make(code, 0, 16)} } func (b *codeBuf) push(instr func(*Thread)) { b.instrs = append(b.instrs, instr) } func (b *codeBuf) nextPC() uint { return uint(len(b.instrs)) } func (b *codeBuf) get() code { // Freeze this buffer into an array of exactly the right size a := make(code, len(b.instrs)) copy(a, b.instrs) return code(a) } /* * User-defined functions */ type evalFunc struct { outer *Frame frameSize int code code } func (f *evalFunc) NewFrame() *Frame { return f.outer.child(f.frameSize) } func (f *evalFunc) Call(t *Thread) { f.code.exec(t) }