Documentation
¶
Overview ¶
Package vm executes compiled Kukel programs on a stack machine.
Each call has a frame. A frame's slots (parameters, locals, hidden slots) sit on the value stack at frame.base, followed by its operand stack. The callee value sits just below the slots.
Index ¶
- Constants
- type Builtins
- type Calls
- type Canceller
- type DebugFrame
- type DebugVar
- type Node
- type ProfFrame
- type ProfileSummary
- type Profiler
- type RuntimeError
- type Sample
- type TraceEntry
- type VM
- func (vm *VM) BuiltinLookup() Builtins
- func (vm *VM) Call(fn value.Value, args []value.Value) (value.Value, error)
- func (vm *VM) Cancellable() *Canceller
- func (vm *VM) CloseOutput()
- func (vm *VM) Config() *native.Config
- func (vm *VM) CurrentCanceller() *Canceller
- func (vm *VM) Done() <-chan struct{}
- func (vm *VM) End() error
- func (vm *VM) Err() error
- func (vm *VM) Extend(prog *bytecode.Program) error
- func (vm *VM) FlushOutput() error
- func (vm *VM) Frames() []DebugFrame
- func (vm *VM) Global(name string) (value.Value, bool)
- func (vm *VM) Globals() []string
- func (vm *VM) Init() error
- func (vm *VM) Local(key any, init func() any) any
- func (vm *VM) NewGenerator(name string, next func() (value.Value, bool, error)) (value.Value, error)
- func (vm *VM) PauseProfile()
- func (vm *VM) Profiler() *Profiler
- func (vm *VM) Program() *bytecode.Program
- func (vm *VM) Rand() *rand.Rand
- func (vm *VM) ResetSteps()
- func (vm *VM) ResumeProfile()
- func (vm *VM) Run(args []string) (int, error)
- func (vm *VM) SetGlobal(name string, v value.Value) bool
- func (vm *VM) SetStderr(w io.Writer)
- func (vm *VM) SetVar(i int, name string, v value.Value) bool
- func (vm *VM) ShareCanceller(c *Canceller)
- func (vm *VM) ShareOutput() (stdout, stderr io.Writer)
- func (vm *VM) Start(fn value.Value, args []value.Value) (value.Value, error)
- func (vm *VM) StartProfile(p *Profiler, interp string)
- func (vm *VM) Started() time.Time
- func (vm *VM) Stderr() io.Writer
- func (vm *VM) Stdin() *bufio.Reader
- func (vm *VM) Stdout() io.Writer
- func (vm *VM) StopProfile()
- func (vm *VM) Thrown(err error) (value.Value, bool)
- func (vm *VM) Vars(i int) []DebugVar
- func (vm *VM) WaitEnd(start time.Time)
- func (vm *VM) WaitStart() time.Time
Constants ¶
const MaxFrames = 10000
MaxFrames bounds the call depth; deeper recursion is a stack overflow.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Builtins ¶
type Builtins func(name string) (*value.BuiltinObj, bool)
Builtins resolves built-in functions by name.
type Calls ¶ added in v0.30.0
Calls names what a call count counts: the calls in interpreter Interp of Kukel function Func, or (Func nil) of the built-in or Go function Go.
type Canceller ¶ added in v0.2.0
type Canceller struct {
// contains filtered or unexported fields
}
Canceller stops a running program from another goroutine. Cancellers form a tree: cancelling one cancels the ones made from it (Child).
func NewCanceller ¶ added in v0.2.1
func NewCanceller() *Canceller
NewCanceller makes a Canceller that nothing has cancelled yet.
func (*Canceller) Cancel ¶ added in v0.2.0
Cancel makes the programs that use c (and its children) stop at their next step with a CancelledError that try cannot catch; Go functions that wait (sleep, receive) return at once. It may be called from any goroutine, and more than once.
func (*Canceller) Child ¶ added in v0.2.1
Child makes a Canceller that is cancelled when c is (at once if c already is).
type DebugFrame ¶ added in v0.15.0
type DebugFrame struct {
Func *bytecode.Function
Line int // the line it is at (where it called the next frame)
This *value.ObjectObj // the object of a member function call, or nil
PC int // the instruction it is at (of the call, for a caller)
}
DebugFrame is a call the program is in, for the debugger.
type DebugVar ¶ added in v0.15.0
DebugVar is a variable of a frame: a parameter, local or captured one.
type Node ¶ added in v0.31.0
type Node struct {
Parent int
Interp string
Func *bytecode.Function
Line int
Time time.Duration
Count int64
}
Node is a node of the call tree of the samples: the function Func at line Line, called from node Parent (an index into the nodes). A root (Parent -1, Func nil) is an interpreter. Time and Count are of the samples whose stack ended at the node.
type ProfFrame ¶ added in v0.30.0
ProfFrame is a function of a sampled stack and the line it was at.
type ProfileSummary ¶ added in v0.31.0
type ProfileSummary struct {
Total time.Duration // the time of the samples
Elapsed time.Duration // the wall time they cover (with CPU, also what was left out)
Samples int64
Interps []string // the interpreters profiled, in the order they started
Running []string // those that run: their calls are counted up to their latest sample
Start time.Time // when the first interpreter started (zero: none did)
Duration time.Duration // from Start to when the last one stopped (or now, while one runs)
}
ProfileSummary sums up what a Profiler collected.
type Profiler ¶ added in v0.30.0
type Profiler struct {
Interval time.Duration // between samples (0 or less: 1 ms)
CPU bool // leave out the time spent waiting in Go functions (see VM.WaitStart)
// contains filtered or unexported fields
}
Profiler collects the samples and call counts of the interpreters it profiles: a program and its workers. Its methods are safe for concurrent use.
func NewProfiler ¶ added in v0.30.0
NewProfiler makes a Profiler.
func (*Profiler) Calls ¶ added in v0.30.0
Calls gives the call counts: exact for the interpreters that stopped (or paused), up to their latest sample for those that run.
func (*Profiler) Samples ¶ added in v0.30.0
Samples gives the stacks of the samples so far (from the call tree).
func (*Profiler) Summary ¶ added in v0.31.0
func (p *Profiler) Summary() ProfileSummary
Summary sums up what p collected so far.
func (*Profiler) Tree ¶ added in v0.31.0
Tree gives the call tree of the samples so far: each node after its parent.
func (*Profiler) WorkerName ¶ added in v0.30.0
WorkerName names a new worker that runs fn: "worker 1: f".
type RuntimeError ¶
type RuntimeError struct {
Value value.Value // the thrown Error object (nil for the step limit, cancellation, exit)
Kind string // its kind (never "": an empty kind becomes the class name)
Msg string // its message ("" without one)
Trace []TraceEntry // innermost call first
Fatal bool // try cannot catch it (exit, the step limit, cancellation)
Exit *int // set by exit(code): not an error, the program ends
// contains filtered or unexported fields
}
RuntimeError is a thrown exception: the thrown value and the stack trace at the throw. It is what Run returns for an exception nobody caught.
func (*RuntimeError) Error ¶
func (e *RuntimeError) Error() string
Error returns the message and the stack trace. Long traces (deep recursion) show only the first and last traceEnds calls.
type Sample ¶ added in v0.30.0
Sample is the time of one call stack: the interpreter (as Interp names it), its frames outermost first, and the time (and the number of samples) that ended there.
type TraceEntry ¶
TraceEntry is one line of a stack trace.
type VM ¶
type VM struct {
// StepLimit, when positive, stops the program with a fatal error after
// that many backward jumps, calls of Kukel functions and thrown
// exceptions: for tests, and for Go programs that run untrusted code
// (the kukel package resets the count for every call from Go).
StepLimit int
// Debug, when set, runs at every BREAK instruction: at the start of each
// source line of code that the debugger made a copy of (Debuggable).
// The VM's frames are then as at the start of that line (Frames). An
// error stops the program (a fatal one, such as exit, ends it).
Debug func(vm *VM) error
// DebugUncaught, when set, runs when an exception is thrown that no
// try of the program catches (a finally does not count), before the
// frames are dropped (Frames). An error it gives ends the program
// instead (a fatal one, such as exit).
DebugUncaught func(vm *VM, re *RuntimeError) error
// contains filtered or unexported fields
}
VM runs one program.
func New ¶
New prepares prog for running: it binds the functions and built-ins to their global slots.
func NewWith ¶ added in v0.2.0
func NewWith(prog *bytecode.Program, builtins Builtins, config *native.Config, stdout io.Writer, stdin io.Reader) (*VM, error)
NewWith is New for a program limited by config (see native.Config): it refuses a program that uses a built-in or module config does not allow.
func (*VM) BuiltinLookup ¶ added in v0.2.0
BuiltinLookup is how the VM found its built-ins (New's builtins).
func (*VM) Call ¶
Call calls fn from a built-in (sort's comparator, for example). The built-in's own arguments stay on the stack below the new call.
func (*VM) Cancellable ¶ added in v0.2.0
Cancellable makes the program cancellable from now on with the returned Canceller (replacing an earlier one). Workers started afterwards share it: cancelling the program cancels them too.
func (*VM) CloseOutput ¶ added in v0.2.1
func (vm *VM) CloseOutput()
CloseOutput flushes the output shared with workers (ShareOutput) and drops what they write later. Run does it when main returns.
func (*VM) CurrentCanceller ¶ added in v0.2.0
CurrentCanceller is the VM's Canceller, or nil.
func (*VM) Done ¶ added in v0.2.0
func (vm *VM) Done() <-chan struct{}
Done implements value.Env: closed when the program is cancelled (nil if it cannot be).
func (*VM) End ¶ added in v0.33.2
End ends what native modules keep for the interpreter until its program ends: each value stored with Local that has a method End() error (the files fs::open opened and the program did not close). It gives the first failure. The command calls it when the program ends, a worker when it ends, and the Go API's Close.
func (*VM) Err ¶ added in v0.2.0
Err implements value.Env: the error for a cancelled program, else nil.
func (*VM) Extend ¶ added in v0.7.0
Extend continues with prog, a program that adds to the VM's program (compiler.Session): globals, classes and functions after the ones the VM has, and member functions defined since for the classes it has. The values of the globals stay.
func (*VM) FlushOutput ¶ added in v0.31.0
FlushOutput flushes the program's standard output if it is buffered (as eprint does), also while workers write to it: for a debugger, before it shows something.
func (*VM) Frames ¶ added in v0.15.0
func (vm *VM) Frames() []DebugFrame
Frames gives the calls the program is in, outermost first; the last is the one at the BREAK the debug hook was called for.
func (*VM) Global ¶ added in v0.2.0
Global returns the value of the global called name: a top-level name of the program ("main"), or a module's ("util::f", "json::encode").
func (*VM) Globals ¶ added in v0.28.0
Globals gives the names of the program's global variables (not its functions and classes), in the order of the program.
func (*VM) Init ¶ added in v0.2.0
Init runs the global initializers, the first time only. If they throw an exception, every later Init gives the same error: the globals are not usable. If the step limit or a cancellation stopped them, the next Init runs them again from the start.
func (*VM) NewGenerator ¶ added in v0.34.0
func (vm *VM) NewGenerator(name string, next func() (value.Value, bool, error)) (value.Value, error)
NewGenerator makes a generator whose values come from next, a function written in Go: it gives the next value, or false at the end. name is how the generator shows ("fs::File::iter"). See native.Generator.
func (*VM) PauseProfile ¶ added in v0.31.0
func (vm *VM) PauseProfile()
PauseProfile stops profiling vm until ResumeProfile: for the Go API, whose calls are profiled but not the time between them. The call counts go to the Profiler. It is called on vm's goroutine.
func (*VM) ResetSteps ¶ added in v0.2.0
func (vm *VM) ResetSteps()
ResetSteps starts counting steps for StepLimit from zero again.
func (*VM) ResumeProfile ¶ added in v0.31.0
func (vm *VM) ResumeProfile()
ResumeProfile goes on profiling vm after PauseProfile.
func (*VM) Run ¶
Run runs the global initializers, then main(args). It returns main's result as the exit code (an int result; anything else is 0).
When main returns, the program ends: if workers share the output (ShareOutput), it is flushed and closed, so that workers still running cannot write any more.
func (*VM) SetGlobal ¶ added in v0.28.0
SetGlobal gives the global variable called name (as Global names it) the value v, and reports whether there is one; functions and classes cannot be changed.
func (*VM) SetVar ¶ added in v0.28.0
SetVar gives the variable name of frame i (as Vars names it; of two with that name, the later one) the value v, and reports whether there is one.
func (*VM) ShareCanceller ¶ added in v0.2.0
ShareCanceller makes vm stop when c is cancelled (for a worker).
func (*VM) ShareOutput ¶ added in v0.2.0
ShareOutput makes the VM's standard output and error safe to use from several goroutines (workers) and returns them; other VMs can write to them too. Calling it again gives the same writers.
func (*VM) Start ¶ added in v0.2.0
Start runs the global initializers, then calls fn(args...) and gives its result. With fn nil it calls main, with args[0] as its parameter if main has one. exit(code) gives a *RuntimeError with Exit set.
func (*VM) StartProfile ¶ added in v0.30.0
StartProfile profiles vm with p from now on, under the name interp, until StopProfile (PauseProfile and ResumeProfile leave out the time between).
func (*VM) Stdout ¶
Stdout, Stderr, Stdin, Call, Rand, Started, Local, Thrown, Done and Err implement value.Env for the built-ins and the native modules.
func (*VM) StopProfile ¶ added in v0.30.0
func (vm *VM) StopProfile()
StopProfile ends the profiling of vm, and gives its call counts to the Profiler. It is called on vm's goroutine, after it ran.
func (*VM) Vars ¶ added in v0.15.0
Vars gives the variables of frame i (an index into Frames), outer scopes first: the captured variables, then the parameters and locals in scope where it is, by their slots. Of two with the same name, the later one is the one the code sees. A function without Locals (from a .kkc file) gives all its slots by SlotNames (a slot that two blocks share has both names).
func (*VM) WaitEnd ¶ added in v0.31.0
WaitEnd tells the VM that the wait WaitStart gave start for ended: with CPU, the next sample leaves its time out.
func (*VM) WaitStart ¶ added in v0.31.0
WaitStart tells the VM that a Go function it called begins to wait (for time, a message, an event, input): see native.Wait. It gives the time for WaitEnd, or the zero time when the VM does not need it (it is not profiled with CPU). It is called on vm's goroutine.