compiler

package
v0.0.0-...-18194de Latest Latest
Warning

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

Go to latest
Published: May 5, 2026 License: BSD-3-Clause Imports: 23 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ByRefBuiltins = map[phpv.ZString]bool{

	"end": true, "reset": true, "next": true, "prev": true,
	"current": true, "key": true, "each": true,

	"sort": true, "rsort": true, "asort": true, "arsort": true,
	"ksort": true, "krsort": true, "usort": true, "uasort": true, "uksort": true,
	"natsort": true, "natcasesort": true, "shuffle": true,

	"array_walk": true, "array_walk_recursive": true,
	"array_push": true, "array_pop": true,
	"array_shift": true, "array_unshift": true,
	"array_splice": true, "array_multisort": true,

	"settype": true, "parse_str": true, "mb_parse_str": true,

	"preg_match": true, "preg_match_all": true, "sscanf": true,
}

ByRefBuiltins lists builtin functions that take at least one argument by reference. The VM emitter falls back to AST for calls to any of these because the VM's value-passing call protocol can't bind a Writable argument.

View Source
var Closure = &phpobj.ZClass{
	Name:         "Closure",
	H:            &phpv.ZClassHandlers{},
	InternalOnly: true,
}

> class Closure

View Source
var PipeResolveCallable func(ctx phpv.Context, v *phpv.ZVal) (phpv.Callable, error)

PipeResolveCallable is set from the core package to avoid circular imports.

View Source
var TryBuildVMClosureBody func(name phpv.ZString, src *phpv.Loc, body phpv.Runnable) phpv.Runnable

TryBuildVMClosureBody is an optional hook installed by the core/vm/vmcompiler package at init time. When set, the compiler invokes it after building each closure body (`function foo() { ... }`, closures, arrow fns) and, if it returns a non-nil Runnable, replaces the AST body with the VM-backed runner.

Returning nil means "VM compilation failed or was declined; keep the AST body". Implementations must be safe to call concurrently and must not mutate the input Runnable.

Set to nil (the zero value) when the vmcompiler is not linked or has disabled itself via env var. Compiler treats nil as "VM disabled".

View Source
var TryBuildVMScript func(src *phpv.Loc, body phpv.Runnable) phpv.Runnable

TryBuildVMScript is the equivalent hook for top-level scripts. It gets the full Runnables and may return a wrapping VM runner.

Functions

func CallInstanceMethod

func CallInstanceMethod(ctx phpv.Context, obj *phpv.ZVal, name phpv.ZString, args []*phpv.ZVal) (*phpv.ZVal, error)

CallInstanceMethod invokes obj->name(args...) with full PHP dispatch semantics: abstract-method check, private/protected visibility against the calling class, __call fallback when inaccessible, late static binding. Used by the VM's OP_OBJECT_CALL so behaviour matches the AST runObjectFunc path byte-for-byte.

The receiver must be a ZtObject ZVal; the caller is responsible for the upstream "method on null/scalar" diagnostic.

func Compile

func Compile(parent phpv.Context, t *tokenizer.Lexer) (phpv.Runnable, error)

func ConnectParentNodes

func ConnectParentNodes(r phpv.Runnable)

func DoInc

func DoInc(ctx phpv.Context, v *phpv.ZVal, inc bool) error

func EmitNoDiscardForMagicCall

func EmitNoDiscardForMagicCall(ctx phpv.Context, method phpv.Callable, className phpv.ZString, virtualMethodName string) error

EmitNoDiscardForMagicCall checks if a magic method (__call/__callStatic) has #[\NoDiscard] and if so, emits the warning using the virtual method name. This is called BEFORE the magic method body executes so the warning appears before any output from the method body.

func EvalBinop

func EvalBinop(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal, loc *phpv.Loc) (*phpv.ZVal, error)

EvalBinop computes the result of a binary operator with full PHP semantics. The VM uses this so its arithmetic / bitwise / compare / concat opcodes match the AST runOperator path byte-for-byte.

Pre-condition: a and b are already evaluated. Loc is the source location of the operator (used for warnings).

Specifically, the dispatch handles:

  • array + array union (PHP's `+` operator on arrays).
  • Object operator overloading via HandleDoOperation (e.g. GMP).
  • PHP 8 TypeError for unsupported operand types (array/resource mixed with numeric ops, completely-non-numeric strings).
  • "A non-numeric value encountered" warnings for leading-numeric strings.
  • Implicit numeric coercion (int / float / bitwise-int).
  • Final dispatch to OperatorMath / OperatorMathLogic / etc. via the operator's op.op pointer.

Compound assignment (op.write) write-back is NOT done here — the caller is responsible. For pure binary ops, op.write is false and this function returns the computed result.

func FormatDeprecatedMsg

func FormatDeprecatedMsg(label, name string, attr *phpv.ZAttribute) string

FormatDeprecatedMsg formats a deprecation message from a #[\Deprecated] attribute. Format rules (matching PHP 8.4+):

  • No args: "Function foo() is deprecated"
  • Message only: "Function foo() is deprecated, msg"
  • Since only: "Function foo() is deprecated since 1.0"
  • Message + since: "Function foo() is deprecated since 1.0, msg"
  • Empty message: "Function foo() is deprecated" (same as no args)

func FunctionTakesByRef

func FunctionTakesByRef(g phpv.GlobalContext, name phpv.ZString) bool

FunctionTakesByRef reports whether the named function (in the current global scope) declares any by-reference parameter. Used by the VM emitter to fall back to AST for calls that need by-ref binding (which the VM's value-passing call protocol can't provide).

Returns false when the function isn't registered yet — pessimistic users should still fall back, but that policy is up to the caller.

func GetChildren

func GetChildren(r phpv.Runnable) []phpv.Runnable

TODO: probably better to go-generate instead

func IsClassConstNode

func IsClassConstNode(r phpv.Runnable) bool

IsClassConstNode reports whether r is one of the AST nodes for class-level constant / static-property / static-method-name access: `Foo::CONST`, `Foo::{$expr}`, `Foo::$bar`, `self::method`, etc. Visibility, interface/parent walking, CompileDelayed resolution and late-static-binding all live in the AST runners; the VM delegates via OP_CLASS_CONST.

func IsClosureNode

func IsClosureNode(r phpv.Runnable) bool

IsClosureNode reports whether r is a *ZClosure (an inline closure or named-function-declaration AST node). When the VM emitter sees this it emits an OpMakeClosure that runs ZClosure.Run — that handles both registration of named functions AND `dup + capture + Spawn` for anonymous closures.

func IsFirstClassCallable

func IsFirstClassCallable(args phpv.Runnables) bool

IsFirstClassCallable checks if args represent a first-class callable syntax.

func IsSlotSafe

func IsSlotSafe(r phpv.Runnable) bool

IsSlotSafe reports whether the function body in r is safe for the VM's slot-only optimization — i.e. local writes can skip mirroring to the FuncContext hashtable.

A body is unsafe when it (transitively) does any of:

  • Calls a builtin that reads or writes locals through the FuncContext (extract, compact, get_defined_vars, parse_str, mb_parse_str, func_get_args, func_num_args, func_get_arg).
  • Uses a variable-variable expression ($$x, runVariableRef).
  • References $GLOBALS (the array-of-globals magic; reads / writes go through the hashtable).
  • Declares a `global $x` or `static $x = …` (both bind locals to storage that lives outside the slot array).
  • Declares a function (`function foo() { … }`) — that function's body may use `global $x` to bind to a top-level local.

func IsVMCompiled

func IsVMCompiled(c phpv.Callable) bool

IsVMCompiled reports whether a callable's body has been replaced by a VM-backed runner. Returns false for AST-only callables, anything non-ZClosure, or when the callable isn't a function (e.g. internal builtins). Used by tests and tooling to confirm the VM gate took effect for a given function.

func OperatorAppend

func OperatorAppend(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)

func OperatorBoolLogic

func OperatorBoolLogic(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)

func OperatorCompare

func OperatorCompare(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)

func OperatorCompareBool

func OperatorCompareBool(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)

OperatorCompareBool performs a bool comparison between two values. In PHP 8, when either operand is bool or null, comparison is always done by casting both to bool.

func OperatorCompareResult

func OperatorCompareResult(op tokenizer.ItemType, cmp int) (*phpv.ZVal, error)

OperatorCompareResult converts a comparison result (cmp) to a ZVal based on the operator.

func OperatorCompareStrict

func OperatorCompareStrict(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)

func OperatorIncDec

func OperatorIncDec(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)

func OperatorMath

func OperatorMath(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)

func OperatorMathLogic

func OperatorMathLogic(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)

func OperatorNot

func OperatorNot(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)

func ResolveAttrArgs

func ResolveAttrArgs(ctx phpv.Context, attr *phpv.ZAttribute) error

ResolveAttrArgs evaluates any lazy argument expressions on the attribute. This must be called before reading attr.Args when expressions couldn't be fully evaluated at compile time (e.g., forward-referenced constants). The caller should set ctx location (via ctx.Tick) to the access site before calling this function so that nested deprecation warnings report the correct location.

func ResolveCallable

func ResolveCallable(ctx phpv.Context, v *phpv.ZVal) (phpv.Callable, phpv.ZObject, error)

ResolveCallable converts a runtime value to a phpv.Callable suitable for ctx.CallZVal. Handles:

  • ZObject with __invoke handler (closures, invokable classes)
  • ZString (function name)
  • ZArray of [object, method] or [class, method]

The second return value is the implicit `$this` (z.this for closures, the array's [0] for object-method array callables, nil otherwise) — pass it as the optionalThis argument to CallZVal so the callee's body sees the right binding.

Returns nil + error otherwise.

func SetDeprecationAlias

func SetDeprecationAlias(name string)

SetDeprecationAlias sets the alias name for the next deprecation check.

func SetNoDiscardAlias

func SetNoDiscardAlias(name string)

SetNoDiscardAlias sets the alias name for the next NoDiscard check.

func ValidateDeprecatedArgs

func ValidateDeprecatedArgs(ctx phpv.Context, attr *phpv.ZAttribute) error

ValidateDeprecatedArgs validates the argument types for #[\Deprecated]. The constructor signature is: __construct(?string $message = "", ?string $since = ""). In strict mode, int/float/bool are rejected. Arrays and objects are always rejected.

func ValidateNoDiscardArgs

func ValidateNoDiscardArgs(ctx phpv.Context, attr *phpv.ZAttribute) error

ValidateNoDiscardArgs validates the argument types for #[\NoDiscard]. The constructor signature is: __construct(?string $message = ""). In strict mode, int/float/bool are rejected. Arrays and objects are always rejected.

Types

type ArrayEntryNode

type ArrayEntryNode interface {
	EntryKey() phpv.Runnable   // nil for un-keyed entry
	EntryValue() phpv.Runnable // never nil
	EntrySpread() bool
}

ArrayEntryNode exposes a single literal-array entry to out-of-package consumers (the bytecode emitter). spread entries (`...$expr`) and keyed entries (`k => v`) are distinguished via IsSpread / Key.

type FirstClassCallableMarker

type FirstClassCallableMarker struct{}

FirstClassCallableMarker is returned by compileFuncPassedArgs when it detects the first-class callable syntax func(...). Callers should check for this and create a closure wrapping the function instead of a regular call.

func (*FirstClassCallableMarker) Dump

func (*FirstClassCallableMarker) Run

type IsInIteration

type IsInIteration interface {
	IsInIteration() bool
}

IsInIteration is implemented by SPL iterators (e.g. RecursiveIteratorIterator) to indicate they've already been rewound and are in iteration state. When true, the foreach engine skips the initial rewind() call.

type NamedArg

type NamedArg struct {
	Name phpv.ZString
	Arg  phpv.Runnable
}

NamedArg wraps a Runnable with a parameter name for PHP 8.0 named arguments.

func (*NamedArg) ArgName

func (n *NamedArg) ArgName() phpv.ZString

func (*NamedArg) Dump

func (n *NamedArg) Dump(w io.Writer) error

func (*NamedArg) Inner

func (n *NamedArg) Inner() phpv.Runnable

func (*NamedArg) Run

func (n *NamedArg) Run(ctx phpv.Context) (*phpv.ZVal, error)

type SpreadArg

type SpreadArg struct {
	Arg phpv.Runnable
}

SpreadArg wraps a Runnable for the argument unpacking syntax: func(...$arr)

func (*SpreadArg) Dump

func (s *SpreadArg) Dump(w io.Writer) error

func (*SpreadArg) Inner

func (s *SpreadArg) Inner() phpv.Runnable

func (*SpreadArg) Run

func (s *SpreadArg) Run(ctx phpv.Context) (*phpv.ZVal, error)

type TryCatchEntry

type TryCatchEntry interface {
	CatchTypes() []phpv.ZString
	CatchVarName() phpv.ZString
	CatchBody() phpv.Runnable
	CatchLoc() *phpv.Loc
}

TryCatchEntry exposes a single catch clause.

type TryNode

type TryNode interface {
	TryBody() phpv.Runnable
	TryCatches() []TryCatchEntry
	TryFinally() phpv.Runnable
}

TryNode exposes a try statement to the bytecode emitter.

type ZClosure

type ZClosure struct {
	phpv.CallableVal
	// contains filtered or unexported fields
}

func (*ZClosure) Call

func (z *ZClosure) Call(ctx phpv.Context, args []*phpv.ZVal) (*phpv.ZVal, error)

func (*ZClosure) ClosureInstanceKey

func (z *ZClosure) ClosureInstanceKey() uintptr

ClosureInstanceKey returns a unique key for this closure instance. This implements phpv.ClosureInstanceKeyProvider and is used by runStaticVar to maintain per-closure-instance static variable storage, so that each closure instance created by a factory function has independent static vars.

func (*ZClosure) Compile

func (c *ZClosure) Compile(ctx phpv.Context) error

func (*ZClosure) Dump

func (c *ZClosure) Dump(w io.Writer) error

func (*ZClosure) DumpArgsAndBody

func (c *ZClosure) DumpArgsAndBody(w io.Writer) error

DumpArgsAndBody dumps "(args) [: returnType] {\n body\n}" for use when the "function name" prefix is already written by the caller (e.g., class method dump).

func (*ZClosure) GetArgs

func (z *ZClosure) GetArgs() []*phpv.FuncArg

func (*ZClosure) GetAttributes

func (z *ZClosure) GetAttributes() []*phpv.ZAttribute

GetAttributes returns the PHP attributes on this function/closure.

func (*ZClosure) GetCalledClass

func (z *ZClosure) GetCalledClass() phpv.ZClass

func (*ZClosure) GetClass

func (z *ZClosure) GetClass() phpv.ZClass

func (*ZClosure) GetDeclLoc

func (z *ZClosure) GetDeclLoc() *phpv.Loc

GetDeclLoc implements phpv.FuncDeclLoc, returning the function's declaration location.

func (*ZClosure) GetReturnType

func (z *ZClosure) GetReturnType() *phpv.TypeHint

func (*ZClosure) GetStaticVars

func (z *ZClosure) GetStaticVars(ctx phpv.Context) []phpv.StaticVarEntry

GetStaticVars returns the current values of static variables in this function in declaration order. For named functions (not closures), each static var's current value is returned. If a static var has never been set, its default (or NULL) is returned. Defaults are evaluated using the provided context if needed.

func (*ZClosure) GetThis

func (z *ZClosure) GetThis() phpv.ZObject

func (*ZClosure) GetUseVars

func (z *ZClosure) GetUseVars() []*phpv.FuncUse

func (*ZClosure) IsGenerator

func (z *ZClosure) IsGenerator() bool

func (*ZClosure) IsStatic

func (z *ZClosure) IsStatic() bool

func (*ZClosure) Loc

func (z *ZClosure) Loc() *phpv.Loc

func (*ZClosure) LocEnd

func (z *ZClosure) LocEnd() *phpv.Loc

func (*ZClosure) Name

func (z *ZClosure) Name() string

func (*ZClosure) ReturnsByRef

func (z *ZClosure) ReturnsByRef() bool

func (*ZClosure) Run

func (closure *ZClosure) Run(ctx phpv.Context) (l *phpv.ZVal, err error)

func (*ZClosure) Spawn

func (z *ZClosure) Spawn(ctx phpv.Context) (*phpv.ZVal, error)

Jump to

Keyboard shortcuts

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