Documentation
¶
Index ¶
- Variables
- func CallInstanceMethod(ctx phpv.Context, obj *phpv.ZVal, name phpv.ZString, args []*phpv.ZVal) (*phpv.ZVal, error)
- func Compile(parent phpv.Context, t *tokenizer.Lexer) (phpv.Runnable, error)
- func ConnectParentNodes(r phpv.Runnable)
- func DoInc(ctx phpv.Context, v *phpv.ZVal, inc bool) error
- func EmitNoDiscardForMagicCall(ctx phpv.Context, method phpv.Callable, className phpv.ZString, ...) error
- func EvalBinop(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal, loc *phpv.Loc) (*phpv.ZVal, error)
- func FormatDeprecatedMsg(label, name string, attr *phpv.ZAttribute) string
- func FunctionTakesByRef(g phpv.GlobalContext, name phpv.ZString) bool
- func GetChildren(r phpv.Runnable) []phpv.Runnable
- func IsClassConstNode(r phpv.Runnable) bool
- func IsClosureNode(r phpv.Runnable) bool
- func IsFirstClassCallable(args phpv.Runnables) bool
- func IsSlotSafe(r phpv.Runnable) bool
- func IsVMCompiled(c phpv.Callable) bool
- func OperatorAppend(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)
- func OperatorBoolLogic(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)
- func OperatorCompare(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)
- func OperatorCompareBool(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)
- func OperatorCompareResult(op tokenizer.ItemType, cmp int) (*phpv.ZVal, error)
- func OperatorCompareStrict(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)
- func OperatorIncDec(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)
- func OperatorMath(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)
- func OperatorMathLogic(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)
- func OperatorNot(ctx phpv.Context, op tokenizer.ItemType, a, b *phpv.ZVal) (*phpv.ZVal, error)
- func ResolveAttrArgs(ctx phpv.Context, attr *phpv.ZAttribute) error
- func ResolveCallable(ctx phpv.Context, v *phpv.ZVal) (phpv.Callable, phpv.ZObject, error)
- func SetDeprecationAlias(name string)
- func SetNoDiscardAlias(name string)
- func ValidateDeprecatedArgs(ctx phpv.Context, attr *phpv.ZAttribute) error
- func ValidateNoDiscardArgs(ctx phpv.Context, attr *phpv.ZAttribute) error
- type ArrayEntryNode
- type FirstClassCallableMarker
- type IsInIteration
- type NamedArg
- type SpreadArg
- type TryCatchEntry
- type TryNode
- type ZClosure
- func (z *ZClosure) Call(ctx phpv.Context, args []*phpv.ZVal) (*phpv.ZVal, error)
- func (z *ZClosure) ClosureInstanceKey() uintptr
- func (c *ZClosure) Compile(ctx phpv.Context) error
- func (c *ZClosure) Dump(w io.Writer) error
- func (c *ZClosure) DumpArgsAndBody(w io.Writer) error
- func (z *ZClosure) GetArgs() []*phpv.FuncArg
- func (z *ZClosure) GetAttributes() []*phpv.ZAttribute
- func (z *ZClosure) GetCalledClass() phpv.ZClass
- func (z *ZClosure) GetClass() phpv.ZClass
- func (z *ZClosure) GetDeclLoc() *phpv.Loc
- func (z *ZClosure) GetReturnType() *phpv.TypeHint
- func (z *ZClosure) GetStaticVars(ctx phpv.Context) []phpv.StaticVarEntry
- func (z *ZClosure) GetThis() phpv.ZObject
- func (z *ZClosure) GetUseVars() []*phpv.FuncUse
- func (z *ZClosure) IsGenerator() bool
- func (z *ZClosure) IsStatic() bool
- func (z *ZClosure) Loc() *phpv.Loc
- func (z *ZClosure) LocEnd() *phpv.Loc
- func (z *ZClosure) Name() string
- func (z *ZClosure) ReturnsByRef() bool
- func (closure *ZClosure) Run(ctx phpv.Context) (l *phpv.ZVal, err error)
- func (z *ZClosure) Spawn(ctx phpv.Context) (*phpv.ZVal, error)
Constants ¶
This section is empty.
Variables ¶
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.
var Closure = &phpobj.ZClass{ Name: "Closure", H: &phpv.ZClassHandlers{}, InternalOnly: true, }
> class Closure
PipeResolveCallable is set from the core package to avoid circular imports.
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".
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 ConnectParentNodes ¶
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 ¶
TODO: probably better to go-generate instead
func IsClassConstNode ¶
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 ¶
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 ¶
IsFirstClassCallable checks if args represent a first-class callable syntax.
func IsSlotSafe ¶
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 ¶
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 OperatorBoolLogic ¶
func OperatorCompare ¶
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 ¶
OperatorCompareResult converts a comparison result (cmp) to a ZVal based on the operator.
func OperatorCompareStrict ¶
func OperatorIncDec ¶
func OperatorMath ¶
func OperatorMathLogic ¶
func OperatorNot ¶
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 ¶
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.
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 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) ClosureInstanceKey ¶
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) DumpArgsAndBody ¶
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) GetAttributes ¶
func (z *ZClosure) GetAttributes() []*phpv.ZAttribute
GetAttributes returns the PHP attributes on this function/closure.
func (*ZClosure) GetCalledClass ¶
func (*ZClosure) GetDeclLoc ¶
GetDeclLoc implements phpv.FuncDeclLoc, returning the function's declaration location.
func (*ZClosure) GetReturnType ¶
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) GetUseVars ¶
func (*ZClosure) IsGenerator ¶
func (*ZClosure) ReturnsByRef ¶
Source Files
¶
- closure.go
- compile-array.go
- compile-attr.go
- compile-attributed.go
- compile-base.go
- compile-class.go
- compile-classref.go
- compile-clone.go
- compile-declare.go
- compile-destructure.go
- compile-dowhile.go
- compile-enum.go
- compile-expr.go
- compile-for.go
- compile-foreach.go
- compile-func.go
- compile-global.go
- compile-if.go
- compile-instanceof.go
- compile-isset.go
- compile-match.go
- compile-namespace.go
- compile-object.go
- compile-property-hooks.go
- compile-quote.go
- compile-return.go
- compile-static.go
- compile-switch.go
- compile-ternary.go
- compile-throw.go
- compile-try-catch.go
- compile-txt.go
- compile-unset.go
- compile-while.go
- compile-yield.go
- compile.go
- dispatch.go
- run-concat.go
- run-constant.go
- run-enum.go
- run-operator.go
- run-zval.go
- run.go
- validate-break.go
- variable.go
- vmaccess.go
- zclosure.go