vm

package
v0.7.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 13, 2026 License: MIT Imports: 33 Imported by: 0

Documentation

Overview

Package vm implements a bytecode virtual machine for Funxy

Index

Constants

View Source
const FrameGrowthIncrement = 512
View Source
const InitialFrameCount = 1024
View Source
const InitialStackSize = 2048

Initial sizes for stack and frames

View Source
const MaxFrameCount = 4096

Maximum call stack depth to prevent infinite recursion and stack overflow

View Source
const MaxStackSize = 1024 * 1024 // 1M elements

Maximum operand stack size to prevent OOM

View Source
const StackGrowthIncrement = 1024

Growth increment when stack/frames need to expand

Variables

View Source
var ErrGasLimitExceeded = errors.New("gas limit exceeded")
View Source
var ErrMemoryLimitExceeded = errors.New("memory limit exceeded")
View Source
var ErrStackLimitExceeded = errors.New("stack limit exceeded")
View Source
var OpcodeNames = map[Opcode]string{
	OP_CONST:     "CONST",
	OP_POP:       "POP",
	OP_POP_BELOW: "POP_BELOW",
	OP_DUP:       "DUP",
	OP_SWAP:      "SWAP",

	OP_ADD: "ADD",
	OP_SUB: "SUB",
	OP_MUL: "MUL",
	OP_DIV: "DIV",
	OP_MOD: "MOD",
	OP_POW: "POW",
	OP_NEG: "NEG",

	OP_BAND:          "BAND",
	OP_BOR:           "BOR",
	OP_BXOR:          "BXOR",
	OP_BNOT:          "BNOT",
	OP_LEN:           "LEN",
	OP_INTERP_CONCAT: "INTERP_CONCAT",
	OP_LSHIFT:        "LSHIFT",
	OP_RSHIFT:        "RSHIFT",

	OP_CONCAT: "CONCAT",
	OP_CONS:   "CONS",

	OP_EQ: "EQ",
	OP_NE: "NE",
	OP_LT: "LT",
	OP_LE: "LE",
	OP_GT: "GT",
	OP_GE: "GE",

	OP_NOT: "NOT",
	OP_AND: "AND",
	OP_OR:  "OR",

	OP_GET_LOCAL:  "GET_LOCAL",
	OP_SET_LOCAL:  "SET_LOCAL",
	OP_GET_GLOBAL: "GET_GLOBAL",
	OP_SET_GLOBAL: "SET_GLOBAL",

	OP_JUMP:          "JUMP",
	OP_JUMP_IF_FALSE: "JUMP_IF_FALSE",
	OP_LOOP:          "LOOP",

	OP_CALL:      "CALL",
	OP_TAIL_CALL: "TAIL_CALL",
	OP_RETURN:    "RETURN",

	OP_CLOSURE:       "CLOSURE",
	OP_GET_UPVALUE:   "GET_UPVALUE",
	OP_SET_UPVALUE:   "SET_UPVALUE",
	OP_CLOSE_UPVALUE: "CLOSE_UPVALUE",

	OP_MAKE_LIST:            "MAKE_LIST",
	OP_MAKE_RECORD:          "MAKE_RECORD",
	OP_MAKE_TUPLE:           "MAKE_TUPLE",
	OP_MAKE_MAP:             "MAKE_MAP",
	OP_SPREAD:               "SPREAD",
	OP_UNWRAP_OR_RETURN:     "UNWRAP_OR_RETURN",
	OP_MATCH_STRING_PATTERN: "MATCH_STRING_PATTERN",
	OP_MATCH_STRING_EXTRACT: "MATCH_STRING_EXTRACT",
	OP_TRAIT_OP:             "TRAIT_OP",
	OP_EVAL_STMT:            "EVAL_STMT",
	OP_TUPLE_SLICE:          "TUPLE_SLICE",
	OP_LIST_SLICE:           "LIST_SLICE",
	OP_CHECK_TUPLE_LEN_GE:   "CHECK_TUPLE_LEN_GE",
	OP_SPREAD_ARG:           "SPREAD_ARG",
	OP_CALL_SPREAD:          "CALL_SPREAD",
	OP_COMPOSE:              "COMPOSE",
	OP_REGISTER_TRAIT:       "REGISTER_TRAIT",
	OP_CALL_TRAIT:           "CALL_TRAIT",
	OP_DEFAULT:              "DEFAULT",
	OP_GET_FIELD:            "GET_FIELD",
	OP_GET_INDEX:            "GET_INDEX",
	OP_OPTIONAL_CHAIN_FIELD: "OPTIONAL_CHAIN_FIELD",
	OP_UNWRAP_OR_PANIC:      "UNWRAP_OR_PANIC",

	OP_CHECK_TAG:          "CHECK_TAG",
	OP_GET_DATA_FIELD:     "GET_DATA_FIELD",
	OP_CHECK_LIST_LEN:     "CHECK_LIST_LEN",
	OP_GET_LIST_REST:      "GET_LIST_REST",
	OP_CHECK_TYPE:         "CHECK_TYPE",
	OP_UPDATE_PATH:        "UPDATE_PATH",
	OP_CALL_METHOD:        "CALL_METHOD",
	OP_COALESCE:           "COALESCE",
	OP_SET_TYPE_NAME:      "SET_TYPE_NAME",
	OP_SET_LIST_ELEM_TYPE: "SET_LIST_ELEM_TYPE",
	OP_GET_LIST_ELEM:      "GET_LIST_ELEM",
	OP_CHECK_TUPLE_LEN:    "CHECK_TUPLE_LEN",
	OP_GET_TUPLE_ELEM:     "GET_TUPLE_ELEM",
	OP_RANGE:              "RANGE",

	OP_NIL:   "NIL",
	OP_TRUE:  "TRUE",
	OP_FALSE: "FALSE",

	OP_CLOSE_SCOPE:        "CLOSE_SCOPE",
	OP_SET_TYPE_CONTEXT:   "SET_TYPE_CONTEXT",
	OP_CLEAR_TYPE_CONTEXT: "CLEAR_TYPE_CONTEXT",

	OP_EXTEND_RECORD:       "EXTEND_RECORD",
	OP_REGISTER_EXTENSION:  "REGISTER_EXTENSION",
	OP_REGISTER_TYPE_ALIAS: "REGISTER_TYPE_ALIAS",

	OP_HALT:      "HALT",
	OP_AUTO_CALL: "AUTO_CALL",
	OP_FORMATTER: "FORMATTER",

	OP_BUILD_MAP_TRANSIENT: "BUILD_MAP_TRANSIENT",
	OP_MAP_TRANSIENT_PUT:   "MAP_TRANSIENT_PUT",
	OP_FREEZE_MAP:          "FREEZE_MAP",

	OP_BUILD_LIST_TRANSIENT:  "BUILD_LIST_TRANSIENT",
	OP_LIST_TRANSIENT_APPEND: "LIST_TRANSIENT_APPEND",
	OP_FREEZE_LIST:           "FREEZE_LIST",
}

OpcodeNames maps opcodes to their string names (for debugging)

Functions

func Disassemble

func Disassemble(chunk *Chunk, name string) string

Disassemble returns a human-readable representation of the bytecode

func GetHostBinarySize added in v0.6.0

func GetHostBinarySize(binaryData []byte) int64

GetHostBinarySize returns the size of the host binary portion of a self-contained binary (i.e., the size WITHOUT the appended bundle data and footer). Strips all layers of appended bundles (handles double-pack scenarios). Returns the full file size if no embedded bundle is detected.

func PackSelfContained added in v0.6.0

func PackSelfContained(hostBinary []byte, bundle *Bundle) ([]byte, error)

PackSelfContained creates a self-contained binary by appending bundle data to the host binary with a footer. Output format: [hostBinary][bundleData][8-byte bundleSize LE][4-byte "FXYS"]

func RunBundle added in v0.6.0

func RunBundle(bundle *Bundle) (evaluator.Object, error)

RunBundle creates a VM and executes a bundle. Errors are returned, not printed.

func SetGlobalBundle added in v0.6.6

func SetGlobalBundle(b *Bundle)

SetGlobalBundle sets the global bundle for library-only mode.

Types

type Breakpoint added in v0.5.0

type Breakpoint struct {
	File   string
	Line   int
	Column int // Optional, 0 means any column
}

Breakpoint represents a breakpoint location

type BuiltinClosure

type BuiltinClosure struct {
	Name string
	Fn   func(args []evaluator.Object) evaluator.Object
}

BuiltinClosure wraps a Go function as a VM-callable closure Used for registering builtin trait implementations

func (*BuiltinClosure) Hash

func (b *BuiltinClosure) Hash() uint32

func (*BuiltinClosure) Inspect

func (b *BuiltinClosure) Inspect() string

func (*BuiltinClosure) RuntimeType

func (b *BuiltinClosure) RuntimeType() typesystem.Type

func (*BuiltinClosure) Type

type Bundle added in v0.6.0

type Bundle struct {
	// MainChunk is the compiled bytecode for the entry script (single-command mode)
	MainChunk *Chunk

	// Modules maps absolute path -> pre-compiled module
	// All user (non-virtual) module dependencies are included
	Modules map[string]*BundledModule

	// TraitDefaults holds pre-compiled trait default methods from the main script
	// Key format: "TraitName.methodName"
	TraitDefaults map[string]*CompiledFunction

	// SourceFile is the original source file path (for error messages)
	SourceFile string

	// Resources holds embedded static files (HTML, images, configs, etc.)
	// Key is the relative path from the source file directory, value is file contents.
	// Populated by --embed flag during build.
	Resources map[string][]byte

	// Commands maps command name -> sub-bundle for multi-command binaries.
	// When set, MainChunk should be nil. Each sub-bundle has its own
	// MainChunk, Modules, and TraitDefaults; Resources are shared from the parent.
	Commands map[string]*Bundle

	// IsInterpreterExtension indicates that this bundle contains commands that
	// extend the interpreter (via 'funxy build --up'). When true, the binary
	// acts as a normal interpreter, but exposes Commands as CLI subcommands.
	IsInterpreterExtension bool

	// IsLibraryOnly indicates that this bundle contains only libraries and no executable entry point.
	// When true, the binary behaves as an interpreter (REPL/Script) with these libraries pre-loaded.
	IsLibraryOnly bool
}

Bundle represents a complete compiled program with all user module dependencies. This is the v2 bytecode format that replaces the single-Chunk v1 format.

Single-command mode: MainChunk is set, Commands is nil/empty. Multi-command mode: MainChunk is nil, Commands maps command names to sub-bundles.

Resources are shared across all commands.
var GlobalBundle *Bundle

GlobalBundle holds the embedded bundle for library-only mode. Set by the CLI when running a binary with IsLibraryOnly=true.

func DeserializeAny added in v0.6.0

func DeserializeAny(data []byte) (*Bundle, error)

DeserializeAny reads bytecode data and returns either a *Bundle (v2) or wraps a legacy *Chunk (v1) into a Bundle for uniform handling.

func ExtractEmbeddedBundle added in v0.6.0

func ExtractEmbeddedBundle(binaryData []byte) (*Bundle, error)

ExtractEmbeddedBundle reads a self-contained binary and extracts the embedded bundle, if present. Returns nil, nil if no embedded bundle is found.

func (*Bundle) CommandNames added in v0.6.2

func (b *Bundle) CommandNames() []string

CommandNames returns sorted list of available command names.

func (*Bundle) EmbedPackage added in v0.6.6

func (b *Bundle) EmbedPackage(path string, mod *BundledModule)

EmbedPackage adds a compiled module to the bundle. This is used by `funxy pkg build` to embed libraries.

func (*Bundle) GetModuleExports added in v0.6.6

func (b *Bundle) GetModuleExports(key string) ([]string, bool)

GetModuleExports returns the exports of a bundled module. This method satisfies the BundleInterface required by modules/loader.go

func (*Bundle) GetModuleTraits added in v0.6.6

func (b *Bundle) GetModuleTraits(key string) (map[string][]string, bool)

GetModuleTraits returns the traits of a bundled module. This method satisfies the BundleInterface required by modules/loader.go

func (*Bundle) IsMultiCommand added in v0.6.2

func (b *Bundle) IsMultiCommand() bool

IsMultiCommand returns true if this bundle contains multiple named commands.

func (*Bundle) ResolveCommand added in v0.6.2

func (b *Bundle) ResolveCommand(name string) *Bundle

ResolveCommand finds the sub-bundle for a given command name. It also inherits shared Resources from the parent bundle.

func (*Bundle) Serialize added in v0.6.0

func (b *Bundle) Serialize() ([]byte, error)

SerializeBundle converts a Bundle to binary format. Format: - Magic number (4 bytes): "FXYB" - Version (1 byte): 0x02 - Gob-encoded Bundle data

func (*Bundle) Validate added in v0.6.4

func (b *Bundle) Validate() error

Validate checks the structural integrity of a deserialized bundle.

type BundledModule added in v0.6.0

type BundledModule struct {
	// Chunk is the compiled bytecode for this module (nil for package groups)
	Chunk *Chunk

	// PendingImports are this module's own import dependencies
	PendingImports []PendingImport

	// Exports lists the exported symbol names
	Exports []string

	// TraitDefaults holds pre-compiled trait default methods from this module
	TraitDefaults map[string]*CompiledFunction

	// Dir is the original directory path of this module
	Dir string

	// Traits maps trait names to their method names.
	// Used to resolve `import "mod" (TraitName)` in bundled mode.
	Traits map[string][]string

	// IsPackageGroup is true if this module combines sub-packages
	IsPackageGroup bool

	// SubModulePaths lists absolute paths of sub-modules (only for package groups)
	SubModulePaths []string
}

BundledModule represents a single pre-compiled user module in the bundle.

type BytecodeFile added in v0.4.5

type BytecodeFile struct {
	Magic   [4]byte // "FXYB"
	Version byte    // 0x01
	Chunk   *Chunk
}

BytecodeFile represents the complete serialized bytecode file

type CallFrame

type CallFrame struct {

	// ImplicitTypeContext is set by trait operators to guide dynamic dispatch
	ImplicitTypeContext string

	// ExplicitTypeContextDepth tracks the depth of explicit context stack when frame started
	ExplicitTypeContextDepth int
	// contains filtered or unexported fields
}

CallFrame represents a single ongoing function call

type CallFrameInfo added in v0.5.0

type CallFrameInfo struct {
	Index        int
	FunctionName string
	File         string
	Line         int
	Column       int
}

CallFrameInfo represents information about a call frame

type Chunk

type Chunk struct {
	// Code is the bytecode instructions
	Code []byte

	// Constants pool - literals, function names, etc.
	Constants []evaluator.Object

	// Lines maps bytecode offset to source line number (for errors)
	Lines []int

	// Columns maps bytecode offset to source column number (for errors)
	Columns []int

	// File is the source file name
	File string

	// PendingImports stores imports needed by this chunk (for compiled bytecode)
	PendingImports []PendingImport
}

Chunk represents a sequence of bytecode instructions

func Deserialize added in v0.4.5

func Deserialize(data []byte) (*Chunk, error)

Deserialize reconstructs a Chunk from binary format

func NewChunk

func NewChunk() *Chunk

NewChunk creates a new empty chunk

func (*Chunk) AddConstant

func (c *Chunk) AddConstant(value evaluator.Object) int

AddConstant adds a constant to the pool and returns its index

func (*Chunk) Len

func (c *Chunk) Len() int

Len returns the number of bytes in the chunk

func (*Chunk) ReadConstantIndex

func (c *Chunk) ReadConstantIndex(offset int) int

ReadConstantIndex reads a 2-byte constant index at offset

func (*Chunk) Serialize added in v0.4.5

func (c *Chunk) Serialize() ([]byte, error)

Serialize converts a Chunk to a binary format using gob encoding Format: - Magic number (4 bytes): 0x46585942 ("FXYB") - Version (1 byte): 0x01 - Gob-encoded Chunk data

func (*Chunk) Write

func (c *Chunk) Write(b byte, line int)

Write adds a byte to the chunk with line info (column defaults to 0)

func (*Chunk) WriteConstant

func (c *Chunk) WriteConstant(value evaluator.Object, line int)

WriteConstant writes OP_CONST followed by the constant index

func (*Chunk) WriteOp

func (c *Chunk) WriteOp(op Opcode, line int)

WriteOp writes an opcode to the chunk

func (*Chunk) WriteOpWithCol

func (c *Chunk) WriteOpWithCol(op Opcode, line, col int)

WriteOpWithCol writes an opcode to the chunk with column info

func (*Chunk) WriteWithCol

func (c *Chunk) WriteWithCol(b byte, line, col int)

WriteWithCol adds a byte to the chunk with line and column info

type CompiledFunction

type CompiledFunction struct {
	Arity         int    // Total number of parameters (not including variadic)
	RequiredArity int    // Number of required parameters (without defaults)
	Chunk         *Chunk // Bytecode
	Name          string // Function name (for debugging)
	LocalCount    int    // Number of local variables (including params)
	UpvalueCount  int    // Number of upvalues this function captures
	IsVariadic    bool   // True if last param is variadic (args...)
	// Defaults stores compiled default values
	// Defaults[i] corresponds to parameter at index RequiredArity + i
	// Can be: constant index (>=0), or -1 if default needs runtime evaluation
	Defaults []int // Constant indices for default values (-1 if complex)
	// DefaultChunks stores bytecode for complex default expressions
	DefaultChunks []*Chunk // Bytecode chunks for defaults that need evaluation
	// TypeInfo stores the function's type signature for getType()
	TypeInfo typesystem.Type
	// LocalNames stores names of local variables for debugging
	// LocalNames[i] is the name of local variable at slot i
	LocalNames []string
}

CompiledFunction represents a function compiled to bytecode

func CompileTraitDefault added in v0.6.0

func CompileTraitDefault(fn *ast.FunctionStatement) (*CompiledFunction, error)

CompileTraitDefault pre-compiles a single trait default method into a CompiledFunction suitable for bundling. At runtime the VM wraps it in a closure when the default is first needed.

func (*CompiledFunction) Hash

func (f *CompiledFunction) Hash() uint32

func (*CompiledFunction) Inspect

func (f *CompiledFunction) Inspect() string

func (*CompiledFunction) RuntimeType

func (f *CompiledFunction) RuntimeType() typesystem.Type

func (*CompiledFunction) Type

type Compiler

type Compiler struct {
	// contains filtered or unexported fields
}

Compiler compiles AST to bytecode

func NewCompiler

func NewCompiler() *Compiler

NewCompiler creates a new compiler for top-level code

func (*Compiler) Compile

func (c *Compiler) Compile(program *ast.Program) (*Chunk, error)

Compile compiles a program to bytecode

func (*Compiler) CompileModule added in v0.6.0

func (c *Compiler) CompileModule(files []*ast.Program) (*Chunk, error)

CompileModule compiles a module (multiple files) into a single Chunk. Unlike Compile, this handles multiple source files concatenated into one chunk. The resulting Chunk includes PendingImports from all files.

func (*Compiler) GetPendingImports

func (c *Compiler) GetPendingImports() []PendingImport

GetPendingImports returns the list of imports that need to be processed

func (*Compiler) GetTypeAliases

func (c *Compiler) GetTypeAliases() map[string]typesystem.Type

GetTypeAliases returns collected type aliases for default() support

func (*Compiler) SetBaseDir

func (c *Compiler) SetBaseDir(dir string)

SetBaseDir sets the base directory for resolving imports

func (*Compiler) SetResolutionMap added in v0.5.3

func (c *Compiler) SetResolutionMap(resMap map[ast.Node]symbols.Symbol)

SetResolutionMap sets the resolution map from analyzer

func (*Compiler) SetSymbolTable added in v0.5.3

func (c *Compiler) SetSymbolTable(st *symbols.SymbolTable)

SetSymbolTable sets the symbol table

func (*Compiler) SetTypeMap

func (c *Compiler) SetTypeMap(typeMap map[ast.Node]typesystem.Type)

SetTypeMap sets the type map from static analyzer

type Debugger added in v0.5.0

type Debugger struct {
	// Enabled flag
	Enabled bool

	// Input/Output for debugger commands
	Input  io.Reader
	Output io.Writer

	// Callback for when debugger stops
	OnStop func(*Debugger, *VM)
	// contains filtered or unexported fields
}

Debugger provides debugging capabilities for the VM

func NewDebugger added in v0.5.0

func NewDebugger() *Debugger

NewDebugger creates a new debugger instance

func (*Debugger) ClearBreakpoints added in v0.5.0

func (d *Debugger) ClearBreakpoints()

ClearBreakpoints removes all breakpoints

func (*Debugger) Continue added in v0.5.0

func (d *Debugger) Continue()

Continue sets debugger to continue mode (run until breakpoint)

func (*Debugger) FormatLocation added in v0.5.0

func (d *Debugger) FormatLocation(file string, line int) string

FormatLocation formats a file:line location string Prefers relative paths for display (for readability)

func (*Debugger) GetBreakpoints added in v0.5.0

func (d *Debugger) GetBreakpoints() []*Breakpoint

GetBreakpoints returns all breakpoints

func (*Debugger) GetCallStack added in v0.5.0

func (d *Debugger) GetCallStack(vm *VM) []CallFrameInfo

GetCallStack returns the current call stack

func (*Debugger) GetCurrentLocation added in v0.5.0

func (d *Debugger) GetCurrentLocation(vm *VM) (file string, line int, column int)

GetCurrentLocation returns the current file and line

func (*Debugger) GetGlobals added in v0.5.0

func (d *Debugger) GetGlobals(vm *VM) map[string]evaluator.Object

GetGlobals returns global variables (filtering out built-in functions)

func (*Debugger) GetLocals added in v0.5.0

func (d *Debugger) GetLocals(vm *VM) map[string]evaluator.Object

GetLocals returns local variables for the current frame

func (*Debugger) GetStack added in v0.5.0

func (d *Debugger) GetStack(vm *VM) []evaluator.Object

GetStack returns the current stack contents

func (*Debugger) PrintCallStack added in v0.5.0

func (d *Debugger) PrintCallStack(vm *VM)

PrintCallStack prints the call stack

func (*Debugger) PrintGlobals added in v0.5.0

func (d *Debugger) PrintGlobals(vm *VM)

PrintGlobals prints global variables

func (*Debugger) PrintLocals added in v0.5.0

func (d *Debugger) PrintLocals(vm *VM)

PrintLocals prints local variables

func (*Debugger) PrintLocation added in v0.5.0

func (d *Debugger) PrintLocation(vm *VM)

PrintLocation prints the current location

func (*Debugger) PrintStack added in v0.5.0

func (d *Debugger) PrintStack(vm *VM)

PrintStack prints the stack

func (*Debugger) RemoveBreakpoint added in v0.5.0

func (d *Debugger) RemoveBreakpoint(file string, line int)

RemoveBreakpoint removes a breakpoint at the given file and line

func (*Debugger) Run added in v0.5.0

func (d *Debugger) Run()

Run sets debugger to run mode (no debugging)

func (*Debugger) SetBreakpoint added in v0.5.0

func (d *Debugger) SetBreakpoint(file string, line int) *Breakpoint

SetBreakpoint sets a breakpoint at the given file and line

func (*Debugger) ShouldBreak added in v0.5.0

func (d *Debugger) ShouldBreak(vm *VM) bool

ShouldBreak checks if execution should break at the current location

func (*Debugger) Step added in v0.5.0

func (d *Debugger) Step()

Step sets debugger to step mode

func (*Debugger) StepOut added in v0.5.0

func (d *Debugger) StepOut(vm *VM)

StepOut sets debugger to step out mode

func (*Debugger) StepOver added in v0.5.0

func (d *Debugger) StepOver(vm *VM)

StepOver sets debugger to step over mode

type DebuggerCLI added in v0.5.0

type DebuggerCLI struct {
	// contains filtered or unexported fields
}

DebuggerCLI provides a command-line interface for the debugger

func NewDebuggerCLI added in v0.5.0

func NewDebuggerCLI(debugger *Debugger, vm *VM) *DebuggerCLI

NewDebuggerCLI creates a new CLI debugger

func (*DebuggerCLI) PrintHelp added in v0.5.0

func (cli *DebuggerCLI) PrintHelp()

PrintHelp prints help information (exported for testing)

func (*DebuggerCLI) Run added in v0.5.0

func (cli *DebuggerCLI) Run()

Run starts the debugger CLI loop

func (*DebuggerCLI) SetInput added in v0.5.0

func (cli *DebuggerCLI) SetInput(r io.Reader)

SetInput sets the input reader

func (*DebuggerCLI) SetOutput added in v0.5.0

func (cli *DebuggerCLI) SetOutput(w io.Writer)

SetOutput sets the output writer

type DebuggerMode added in v0.5.0

type DebuggerMode int

DebuggerMode represents the current debugging mode

const (
	// ModeRun - normal execution (no debugging)
	ModeRun DebuggerMode = iota
	// ModeStep - step through instructions one at a time
	ModeStep
	// ModeStepOver - step over function calls
	ModeStepOver
	// ModeStepOut - step out of current function
	ModeStepOut
	// ModeContinue - continue until next breakpoint
	ModeContinue
)

type FunctionType

type FunctionType int

FunctionType distinguishes top-level code from functions

const (
	TYPE_SCRIPT FunctionType = iota
	TYPE_FUNCTION
)

type LibraryBundleMarker added in v0.6.6

type LibraryBundleMarker struct{}

IsLibraryOnly indicates that this bundle contains only libraries and no executable entry point. Used for "funxy pkg build" to create a binary that acts as a custom interpreter.

type Local

type Local struct {
	Name       string
	Depth      int  // Scope depth where this local was declared
	Slot       int  // Stack slot relative to frame.base
	IsCaptured bool // True if captured by a nested function (needs to become upvalue)
}

Local represents a local variable during compilation

type LoopContext

type LoopContext struct {
	// contains filtered or unexported fields
}

LoopContext tracks loop information for break/continue

type MetricsHandler added in v0.7.0

type MetricsHandler interface {
	RecordAllocationsPerSec(uint64)
	RecordInstructionsPerSec(uint64)
}

type ModuleScope added in v0.4.8

type ModuleScope struct {
	Globals *PersistentMap
}

ModuleScope wraps globals for shared access

func NewModuleScope added in v0.4.8

func NewModuleScope() *ModuleScope

NewModuleScope creates a new module scope

type ObjClosure

type ObjClosure struct {
	Function *CompiledFunction
	Upvalues []*ObjUpvalue
	Globals  *ModuleScope // Shared mutable scope for module globals
}

ObjClosure wraps a CompiledFunction with its captured upvalues

func (*ObjClosure) Hash

func (c *ObjClosure) Hash() uint32

func (*ObjClosure) Inspect

func (c *ObjClosure) Inspect() string

func (*ObjClosure) RuntimeType

func (c *ObjClosure) RuntimeType() typesystem.Type

func (*ObjClosure) Type

func (c *ObjClosure) Type() evaluator.ObjectType

type ObjRange added in v0.5.0

type ObjRange struct {
	Start Value
	Next  Value // ValNil if not present
	End   Value
}

ObjRange represents a range [Start, End) or [Start, Next, End)

func (*ObjRange) Hash added in v0.5.0

func (r *ObjRange) Hash() uint32

func (*ObjRange) Inspect added in v0.5.0

func (r *ObjRange) Inspect() string

func (*ObjRange) RuntimeType added in v0.5.0

func (r *ObjRange) RuntimeType() typesystem.Type

func (*ObjRange) Type added in v0.5.0

func (r *ObjRange) Type() evaluator.ObjectType

type ObjUpvalue

type ObjUpvalue struct {
	// When open: Location points to the stack slot index
	// When closed: Location is -1 and Closed holds the value
	Location int
	Closed   evaluator.Object

	// For the VM's open upvalue list (singly linked, sorted by location)
	Next *ObjUpvalue
}

ObjUpvalue represents a captured variable from an enclosing scope It can be "open" (pointing to stack) or "closed" (holding value directly)

type Opcode

type Opcode byte

Opcode represents a single VM instruction

const (
	// Stack manipulation
	OP_CONST     Opcode = iota // Push constant from pool
	OP_POP                     // Discard top of stack
	OP_POP_BELOW               // Discard item below top N items: [..., val, a, b] -> [..., a, b]
	OP_DUP                     // Duplicate top of stack
	OP_SWAP                    // Swap top two stack elements

	// Arithmetic
	OP_ADD // +
	OP_SUB // -
	OP_MUL // *
	OP_DIV // /
	OP_MOD // %
	OP_POW // **
	OP_NEG // Unary minus

	// Bitwise operations
	OP_BAND          // &
	OP_BOR           // |
	OP_BXOR          // ^
	OP_BNOT          // ~ (unary)
	OP_LEN           // len (unary)
	OP_INTERP_CONCAT // string interpolation concat
	OP_LSHIFT        // <<
	OP_RSHIFT        // >>

	// List/String operations
	OP_CONCAT // ++
	OP_CONS   // ::

	// Comparison
	OP_EQ // ==
	OP_NE // !=
	OP_LT // <
	OP_LE // <=
	OP_GT // >
	OP_GE // >=

	// Logic
	OP_NOT // !
	OP_AND // &&
	OP_OR  // ||

	// Variables (Phase 2)
	OP_GET_LOCAL  // Get local variable by index
	OP_SET_LOCAL  // Set local variable by index
	OP_GET_GLOBAL // Get global variable by name
	OP_SET_GLOBAL // Set global variable by name

	// Control flow (Phase 3)
	OP_JUMP          // Unconditional jump
	OP_JUMP_IF_FALSE // Jump if top of stack is false
	OP_LOOP          // Jump backward (for loops)

	// Functions (Phase 4)
	OP_CALL      // Call function
	OP_TAIL_CALL // Tail call optimization - reuse current frame
	OP_RETURN    // Return from function

	// Closures (Phase 6)
	OP_CLOSURE       // Create closure
	OP_GET_UPVALUE   // Get captured variable
	OP_SET_UPVALUE   // Set captured variable
	OP_CLOSE_UPVALUE // Close upvalue when leaving scope

	// Data structures (Phase 7)
	OP_MAKE_LIST            // Create list
	OP_MAKE_RECORD          // Create record
	OP_MAKE_TUPLE           // Create tuple
	OP_MAKE_MAP             // Create map
	OP_SPREAD               // Spread list/tuple elements
	OP_UNWRAP_OR_RETURN     // Unwrap Option/Result or early return
	OP_MATCH_STRING_PATTERN // Match string pattern with captures (legacy)
	OP_MATCH_STRING_EXTRACT // Match string, pop input, push bool + captures
	OP_TRAIT_OP             // Trait-based operator dispatch
	OP_EVAL_STMT            // Evaluate AST statement via evaluator
	OP_TUPLE_SLICE          // Get slice of tuple: [tuple, start] -> [slice]
	OP_LIST_SLICE           // Get slice of list: [list, start] -> [slice]
	OP_CHECK_TUPLE_LEN_GE   // Check tuple length >= N (for spread patterns)
	OP_SPREAD_ARG           // Mark argument as spread (to be unpacked)
	OP_CALL_SPREAD          // Call with spread arguments
	OP_COMPOSE              // Function composition: f ,, g
	OP_REGISTER_TRAIT       // Register trait method: [closure] traitIdx typeIdx methodIdx
	OP_CALL_TRAIT           // Call trait method for operator
	OP_DEFAULT              // Get default value for type
	OP_GET_FIELD            // Get record field
	OP_GET_INDEX            // Get list/map element
	OP_OPTIONAL_CHAIN_FIELD // Optional chaining: obj?.field
	OP_UNWRAP_OR_PANIC      // Unwrap Option/Result or panic (for |>> operator)

	// Pattern matching (Phase 7)
	OP_CHECK_TAG          // Check DataInstance.Name == constant, push bool
	OP_GET_DATA_FIELD     // Get DataInstance.Fields[index], push value
	OP_CHECK_LIST_LEN     // Check list length (==, >=), push bool
	OP_GET_LIST_REST      // Get rest of list from index
	OP_CHECK_TYPE         // Check if value is of given type
	OP_UPDATE_PATH        // Deep immutable update: [base, path..., value] -> [new_base]
	OP_CALL_METHOD        // Call method on object (extension methods or field access + call)
	OP_COALESCE           // Null coalescing: push (unwrapped, true) or (original, false)
	OP_MAKE_ITER          // Convert iterable to iterator (handles Iter trait)
	OP_SET_TYPE_NAME      // Set TypeName on RecordInstance (for type annotations)
	OP_SET_LIST_ELEM_TYPE // Set ElementType on List (for List<T> annotations)
	OP_ITER_NEXT          // Get next item from iterator (handles both index-based and lazy)
	OP_GET_LIST_ELEM      // Get list element by index
	OP_CHECK_TUPLE_LEN    // Check tuple length, push bool
	OP_GET_TUPLE_ELEM     // Get tuple element by index
	OP_RANGE              // Create range object: [start, next?, end] -> [range]

	// Special
	OP_NIL   // Push nil
	OP_TRUE  // Push true
	OP_FALSE // Push false

	// Scope management
	OP_CLOSE_SCOPE // Close scope: pop n locals but keep result

	// Type context for ClassMethod dispatch
	OP_SET_TYPE_CONTEXT   // Set expected type for ClassMethod dispatch
	OP_CLEAR_TYPE_CONTEXT // Clear type context

	OP_EXTEND_RECORD // Extend record with new fields: [base, key, val, ...] -> [new_record]

	OP_REGISTER_EXTENSION  // Register extension method: [closure] typeNameIdx methodNameIdx
	OP_REGISTER_TYPE_ALIAS // Register type alias: [typeObject] nameIdx

	// Halt
	OP_HALT // Stop execution

	OP_AUTO_CALL // Auto-call nullary method if type context is set
	OP_FORMATTER // Create format string function: [constant_index] -> [closure]

	// Map Comprehensions (Transient builder pattern)
	OP_BUILD_MAP_TRANSIENT // Creates a temporary MapBuilder on stack
	OP_MAP_TRANSIENT_PUT   // Pops value, key and adds to MapBuilder
	OP_FREEZE_MAP          // Converts MapBuilder to PersistentMap

	// List Comprehensions (Transient builder pattern)
	OP_BUILD_LIST_TRANSIENT  // Creates a temporary ListBuilder on stack
	OP_LIST_TRANSIENT_APPEND // Pops value and appends to ListBuilder
	OP_FREEZE_LIST           // Converts ListBuilder to List
)

type PendingImport

type PendingImport struct {
	Path           string   // Module path (e.g., "lib/test")
	ImportAll      bool     // import (*)
	Symbols        []string // Specific symbols to import
	ExcludeSymbols []string // Symbols to exclude when ImportAll is true
	Alias          string   // Module alias for "import as" syntax
}

PendingImport represents an import that needs to be processed before VM runs

type PersistentMap

type PersistentMap = evaluator.StringMap

PersistentMap is an alias for evaluator.StringMap — string-keyed immutable HAMT.

func EmptyMap

func EmptyMap() *PersistentMap

EmptyMap returns an empty persistent map

type StringPatternParts

type StringPatternParts struct {
	Parts []ast.StringPatternPart
}

StringPatternParts holds pattern parts for string pattern matching

func (*StringPatternParts) Hash

func (s *StringPatternParts) Hash() uint32

func (*StringPatternParts) Inspect

func (s *StringPatternParts) Inspect() string

func (*StringPatternParts) RuntimeType

func (s *StringPatternParts) RuntimeType() typesystem.Type

func (*StringPatternParts) Type

type Upvalue

type Upvalue struct {
	Index   uint8 // Index of the local/upvalue in enclosing scope
	IsLocal bool  // True if captures a local, false if captures another upvalue
}

Upvalue represents a captured variable from an enclosing scope

type VM

type VM struct {

	// Metrics for System Monitoring
	InstructionCount uint64
	AllocatedBytes   uint64

	// Current Rate Metrics (updated every second)
	CurrentAllocationsPerSec  uint64
	CurrentInstructionsPerSec uint64

	// Execution Limits
	MaxAllocBytes          uint64
	MaxAllocBytesPerSecond uint64
	MaxInstructions        uint64
	MaxInstructionsPerSec  uint64
	MaxStackDepth          int

	// Optional metrics handler
	MetricsHandler MetricsHandler

	// Context for cancellation
	Context context.Context
	// contains filtered or unexported fields
}

VM is the virtual machine that executes bytecode

func New

func New() *VM

New creates a new VM instance

func (*VM) AddAllocatedBytes added in v0.7.0

func (vm *VM) AddAllocatedBytes(size uint64) error

AddAllocatedBytes safely increments the allocated bytes counter and checks against the limit.

func (*VM) CallFunction added in v0.5.2

func (vm *VM) CallFunction(fn evaluator.Object, args []evaluator.Object) (evaluator.Object, error)

CallFunction calls a function with arguments

func (*VM) CompileAndExecuteModule added in v0.5.3

func (vm *VM) CompileAndExecuteModule(mod *modules.Module) (*evaluator.RecordInstance, error)

CompileAndExecuteModule compiles a module's files and executes them. This is exported for running entry packages through the VM backend.

func (*VM) DisableDebugger added in v0.5.0

func (vm *VM) DisableDebugger()

DisableDebugger disables debugging

func (*VM) EnableDebugger added in v0.5.0

func (vm *VM) EnableDebugger()

EnableDebugger enables debugging

func (*VM) FastForkVM added in v0.7.7

func (vm *VM) FastForkVM() *VM

FastForkVM creates a thread-safe copy of the VM using pooled resources

func (*VM) Fork added in v0.7.7

func (vm *VM) Fork() *evaluator.Evaluator

Fork implements evaluator.Forker interface

func (*VM) ForkVM

func (vm *VM) ForkVM() *VM

ForkVM creates a thread-safe copy of the VM for isolated execution

func (*VM) GetDebugger added in v0.5.0

func (vm *VM) GetDebugger() *Debugger

GetDebugger returns the debugger instance

func (*VM) GetEvaluator added in v0.7.0

func (vm *VM) GetEvaluator() *evaluator.Evaluator

GetEvaluator returns the evaluator instance for this VM

func (*VM) GetEvaluatorMetrics added in v0.7.0

func (vm *VM) GetEvaluatorMetrics() map[string]uint64

GetEvaluatorMetrics returns metrics from the internal evaluator (Deprecated: use GetMetrics)

func (*VM) GetGlobals added in v0.5.2

func (vm *VM) GetGlobals() *PersistentMap

GetGlobals returns the current global map

func (*VM) GetLoader added in v0.7.0

func (vm *VM) GetLoader() *modules.Loader

GetLoader returns the module loader

func (*VM) GetMetrics added in v0.7.0

func (vm *VM) GetMetrics() map[string]uint64

GetMetrics returns metrics from the VM and internal evaluator

func (*VM) GetStackTrace added in v0.7.0

func (vm *VM) GetStackTrace() string

GetStackTrace returns the current call stack of the VM

func (*VM) LookupBuiltinOperator

func (vm *VM) LookupBuiltinOperator(typeName, operator string) *BuiltinClosure

LookupBuiltinOperator finds a builtin operator method for a type

func (*VM) LookupOperator

func (vm *VM) LookupOperator(typeName, operator string) *ObjClosure

LookupOperator finds an operator method for a type (searches all traits)

func (*VM) LookupTraitMethod

func (vm *VM) LookupTraitMethod(traitName, typeName, methodName string) *ObjClosure

LookupTraitMethod finds a trait method for a given type

func (*VM) LookupTraitMethodAny

func (vm *VM) LookupTraitMethodAny(traitName, typeName, methodName string) evaluator.Object

LookupTraitMethodAny finds a trait method, returning either ObjClosure or BuiltinClosure

func (*VM) LookupTraitMethodFuzzy added in v0.5.0

func (vm *VM) LookupTraitMethodFuzzy(traitName, methodName string, args []evaluator.Object, context string) evaluator.Object

LookupTraitMethodFuzzy finds a trait method by matching argument types against instance keys

func (*VM) PrepareForBundle added in v0.7.0

func (vm *VM) PrepareForBundle(bundle *Bundle)

PrepareForBundle configures the VM to run bytecode from a pre-compiled bundle (e.g. .fbc). Call before Run/RunChunk when executing from a bundle. Sets bundle, baseDir, trait defaults.

func (*VM) ProcessImports

func (vm *VM) ProcessImports(imports []PendingImport) error

ProcessImports processes all pending imports

func (*VM) RegisterBuiltins

func (vm *VM) RegisterBuiltins()

RegisterBuiltins registers all standard builtins in VM globals

func (*VM) RegisterFPTraits

func (vm *VM) RegisterFPTraits()

RegisterFPTraits registers Functional Programming traits and operators into VM globals

func (*VM) RegisterTraitMethod

func (vm *VM) RegisterTraitMethod(traitName, typeName, methodName string, closure *ObjClosure)

RegisterTraitMethod registers a compiled method for a trait/type combination

func (*VM) Release added in v0.7.7

func (vm *VM) Release()

Release returns resources to the pool.

func (*VM) Run

func (vm *VM) Run(chunk *Chunk) (result evaluator.Object, err error)

executeOneOp executes a single opcode (except RETURN and HALT)

func (*VM) SetBaseDir

func (vm *VM) SetBaseDir(dir string)

SetBaseDir sets the base directory for resolving relative imports

func (*VM) SetBundle added in v0.6.0

func (vm *VM) SetBundle(b *Bundle)

SetBundle sets the bytecode bundle for self-contained execution. When set, the VM resolves user module imports from the bundle instead of loading from disk.

func (*VM) SetContext added in v0.5.3

func (vm *VM) SetContext(ctx context.Context)

SetContext sets the context for cancellation

func (*VM) SetCurrentFile

func (vm *VM) SetCurrentFile(file string)

SetCurrentFile sets the current file name for error messages

func (*VM) SetEvaluator

func (vm *VM) SetEvaluator(eval *evaluator.Evaluator)

SetEvaluator sets the evaluator to use for builtin calls

func (*VM) SetGlobal

func (vm *VM) SetGlobal(name string, value evaluator.Object)

SetGlobal sets a global variable

func (*VM) SetGlobals added in v0.5.2

func (vm *VM) SetGlobals(globals *PersistentMap)

SetGlobals sets the global map

func (*VM) SetHostHandlers added in v0.5.2

func (vm *VM) SetHostHandlers(
	call func(reflect.Value, []evaluator.Object) (evaluator.Object, error),
	toVal func(interface{}) (evaluator.Object, error),
)

SetHostHandlers sets the handlers for host object interaction

func (*VM) SetLoader

func (vm *VM) SetLoader(loader *modules.Loader)

SetLoader sets the module loader for resolving imports

func (*VM) SetOutput

func (vm *VM) SetOutput(w io.Writer)

SetOutput sets the output writer for the VM (and its internal evaluator)

func (*VM) SetTraitDefaults

func (vm *VM) SetTraitDefaults(defaults map[string]*ast.FunctionStatement)

SetTraitDefaults sets the trait default implementations from analyzer

func (*VM) SetTypeAliases

func (vm *VM) SetTypeAliases(aliases map[string]typesystem.Type)

SetTypeAliases sets the type aliases from compiler

func (*VM) SetTypeMap

func (vm *VM) SetTypeMap(typeMap map[ast.Node]typesystem.Type)

SetTypeMap sets the type map from analyzer

type VMComposedFunction

type VMComposedFunction struct {
	F evaluator.Object // First function to apply (after G)
	G evaluator.Object // Second function to apply (first)
}

VMComposedFunction represents f ,, g - native VM function composition

func (*VMComposedFunction) Hash

func (c *VMComposedFunction) Hash() uint32

func (*VMComposedFunction) Inspect

func (c *VMComposedFunction) Inspect() string

func (*VMComposedFunction) RuntimeType

func (c *VMComposedFunction) RuntimeType() typesystem.Type

func (*VMComposedFunction) Type

type Value

type Value struct {
	Type ValueType
	Data uint64           // Stores int64 bits, float64 bits, or bool (0/1)
	Obj  evaluator.Object // Holds heap objects (pointers) to keep them alive for GC
}

Value is a stack-allocated tagged union. It avoids heap allocation for small primitives (Int, Float, Bool, Nil). Size: ~24 bytes on 64-bit systems (1 byte type + 7 padding + 8 data + 8 pointer).

func BoolVal

func BoolVal(v bool) Value

func FloatVal

func FloatVal(v float64) Value

func IntVal

func IntVal(v int64) Value

func NilVal

func NilVal() Value

func ObjVal

func ObjVal(o evaluator.Object) Value

func ObjectToValue

func ObjectToValue(obj evaluator.Object) Value

Helper to convert Object to Value (unboxing)

func (Value) AsBool

func (v Value) AsBool() bool

func (Value) AsFloat

func (v Value) AsFloat() float64

func (Value) AsInt

func (v Value) AsInt() int64

func (Value) AsObject

func (v Value) AsObject() evaluator.Object

Conversion to evaluator.Object (boxing) - for compatibility/return

func (Value) Equals

func (v Value) Equals(other Value) bool

Equality check

func (Value) Hash

func (v Value) Hash() uint32

Hash returns hash code

func (Value) Inspect

func (v Value) Inspect() string

Inspect returns string representation

func (Value) IsBool

func (v Value) IsBool() bool

func (Value) IsFloat

func (v Value) IsFloat() bool

func (Value) IsInt

func (v Value) IsInt() bool

func (Value) IsNil

func (v Value) IsNil() bool

func (Value) IsObj

func (v Value) IsObj() bool

func (Value) RuntimeType

func (v Value) RuntimeType() typesystem.Type

RuntimeType returns the type info

type ValueType

type ValueType uint8

ValueType identifies the type of value stored in the Value struct

const (
	ValNil ValueType = iota
	ValInt
	ValFloat
	ValBool
	ValObj // Complex object (String, List, Map, etc.)
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL