mirror of
https://github.com/golang/go.git
synced 2025-05-19 06:14:40 +00:00
change eval functions from taking *Frame to *Thread R=austin DELTA=500 (7 added, 4 deleted, 489 changed) OCL=34256 CL=34260
85 lines
1.4 KiB
Go
85 lines
1.4 KiB
Go
// 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
|
|
|
|
/*
|
|
* Virtual machine
|
|
*/
|
|
|
|
type Thread struct {
|
|
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) {
|
|
v := Thread{0, t.f}; // TODO: reuse t
|
|
l := uint(len(i));
|
|
for v.pc < l {
|
|
pc := v.pc;
|
|
v.pc++;
|
|
i[pc](&v);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Code buffer
|
|
*/
|
|
|
|
type codeBuf struct {
|
|
instrs code;
|
|
}
|
|
|
|
func newCodeBuf() *codeBuf {
|
|
return &codeBuf{make(code, 0, 16)};
|
|
}
|
|
|
|
func (b *codeBuf) push(instr func(*Thread)) {
|
|
n := len(b.instrs);
|
|
if n >= cap(b.instrs) {
|
|
a := make(code, n, n*2);
|
|
for i := range b.instrs {
|
|
a[i] = b.instrs[i];
|
|
}
|
|
b.instrs = a;
|
|
}
|
|
b.instrs = b.instrs[0:n+1];
|
|
b.instrs[n] = 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));
|
|
for i := range b.instrs {
|
|
a[i] = b.instrs[i];
|
|
}
|
|
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);
|
|
}
|