There are two main motivations to this:
a) The logic for handling internal and userland observation can be unified.
b) Unwinding of observed functions on a bailout does notably not include observers. Even if users of observers were to ensure such handling themselves, it would be impossible to retain the relative ordering - either the user has to unwind all internal observed frames before the automatic unwinding (zend_observer_fcall_end_all) or afterwards, but not properly interleaved.
Signed-off-by: Bob Weinand <bobwei9@hotmail.com>
https://wiki.php.net/rfc/strtolower-ascii means that these functions no longer
depend on the current locale in php 8.2. Before that, this was unsafe to
evaluate at compile time.
Followup to GH-7506
Add strcmp/strcasecmp/strtolower/strtoupper functions
Add bin2hex/hex2bin and related functions
Update test of garbage collection using strtolower to use something else to create a refcounted string
For FETCH_DIM_W etc encode the context it is being used in
(dim, obj, ref or incdec) so we can throw an appropriate error
message for invalid string offset use, in a way that does not
require inspecting neighboring opcodes. The implementation is
similar to the flags used for FETCH_OBJ.
This means that we do not have to be careful about preserving
following opcodes during optimization.
Closes GH-7599.
Add additional zend_compile_position argument, which can be either
AT_SHEBANG, AT_OPEN_TAG or AFTER_OPEN_TAG. The previous behavior
corresponds to AFTER_OPEN_TAG.
Closes GH-7462.
It's possible for delayed early binding opcodes to get optimized
away if they are "unreachable". However, we still need to attempt
early binding for them. (In some cases we also corrupt the early
binding list outright during optimization, which is how I got here.)
Fix this by storing information about delayed early binding
independently of DECLARE_CLASS_DELAYED opcodes, so early binding is
performed even after the opcode has been dropped.
Same as with the IteratorAggregate case, allow reusing get_iterator
if none of the Iterator methods are overridden. Drop the
REUSE_GET_ITERATOR flag that previously allowed ArrayIterator to
opt-in to unconditional get_iterator reuse, and drop the override
handling it did, in favor of the automated approach.
This makes it more likely that unintentional uses of UNUSED
operands will result in crash rather than some hard to detect
corruption of the call frame.
Instead always use the unlinked_uses table, which is already used
if opcache is used. Not much point in having a different mechanism
for the non-opcache case.
Having all property types resolved is no longer a hard requirement
for preloading, resolving the types is just an optimization. As
such, drop the special logic that forced loading of property
types when include-based preloading is used. Instead only keep
the code that resolves types based on actually preloaded classes.
Also drop the ZEND_ACC_PROPERTY_TYPES_RESOLVED flag, which is now
nearly useless and takes up flag space...
If fast_shutdown is used, then we don't need to destroy static
members at all. If fast_shutdown is not used, then we already
loop over classes to destroy static members and static variables
in methods.
Add support for readonly properties, for which only a single
initializing assignment from the declaring scope is allowed.
RFC: https://wiki.php.net/rfc/readonly_properties_v2
Closes GH-7089.
This prevents serialization and unserialization of a class and its
children in a way that does not depend on the zend_class_serialize_deny
and zend_class_unserialize_deny handlers that will be going away
in PHP 9 together with the Serializable interface.
In stubs, `@not-serializable` can be used to set this flag.
This patch only uses the new flag for a handful of Zend classes,
converting the remainder is left for later.
Closes GH-7249.
Fixes bug #81111.
Add support for new expressions inside parameter default values,
static variable initializers, global constant initializers and
attribute arguments.
RFC: https://wiki.php.net/rfc/new_in_initializers
Closes GH-7153.
This PR corrects misspellings identified by the check-spelling action.
The misspellings have been reported at jsoref@b6ba3e2#commitcomment-48946465
The action reports that the changes in this PR would make it happy: jsoref@602417c
Closes GH-6822.
Currently, dynamically declared functions and closures are inserted
into the function table under a runtime definition key, and then later
possibly renamed. When opcache is not used and a file containing a
closure is repeatedly included, this leads to a very large memory leak,
as the no longer needed closure declarations will never be freed
(https://bugs.php.net/bug.php?id=76982).
With this patch, dynamic functions are instead stored in a
dynamic_func_defs member on the op_array, which opcodes reference
by index. When the parent op_array is destroyed, the dynamic_func_defs
it contains are also destroyed (unless they are stilled used elsewhere,
e.g. because they have been bound, or are used by a live closure). This
resolves the fundamental part of the leak, though doesn't completely
fix it yet due to some arena allocations.
The main non-obvious change here is to static variable handling:
We can't destroy static_variables_ptr in destroy_op_array, as e.g.
that would clear the static variables in a dynamic function when
the op_array containing it is destroyed. Static variable destruction
is separated out for this reason (we already do static variable
destruction separately for normal functions, so we only need to
handle main scripts).
Closes GH-5595.
When a method is inherited, the static variables will now always
use the initial values, rather than the values at the time of
inheritance. As such, behavior no longer depends on whether
inheritance happens before or after a method has been called.
This is implemented by always keeping static_variables as the
original values, and static_variables_ptr as the modified copy.
Closes GH-6705.
This is a new transparent technology that eliminates overhead of PHP class inheritance.
PHP classes are compiled and cached (by opcahce) separately, however their "linking" was done at run-time - on each request. The process of "linking" may involve a number of compatibility checks and borrowing methods/properties/constants form parent and traits. This takes significant time, but the result is the same on each request.
Inheritance Cache performs "linking" for unique set of all the depending classes (parent, interfaces, traits, property types, method types involved into compatibility checks) once and stores result in opcache shared memory. As a part of the this patch, I removed limitations for immutable classes (unresolved constants, typed properties and covariant type checks). So now all classes stored in opcache are "immutable". They may be lazily loaded into process memory, if necessary, but this usually occurs just once (on first linking).
The patch shows 8% improvement on Symphony "Hello World" app.
To avoid increasing the size of parser stack elements by storing
size_t offset and length, this instead only stores the start
offset (or rather pointer now) and determines the length of the
identifier in zend_lex_tstring.
We're starting to see a mix between uses of zend_bool and bool.
Replace all usages with the standard bool type everywhere.
Of course, zend_bool is retained as an alias.
Instead of setting the old AST type to zero, replace the AST with
the compiled constexpr AST zval. This requires passing in a
zend_ast** instead of a zend_ast*.
This allows compiling ASTs containing constexprs multiple times
-- the second time, the existing compiled representation will be
resused.
This means we no longer need to copy the attributes AST for
promoted properties.
Voidification of Zend API which always succeeded
Use bool argument types instead of int for boolean arguments
Use bool return type for functions which return true/false (1/0)
Use zend_result return type for functions which return SUCCESS/FAILURE as they don't follow normal boolean semantics
Closes GH-6002
From an engine perspective, named parameters mainly add three
concepts:
* The SEND_* opcodes now accept a CONST op2, which is the
argument name. For now, it is looked up by linear scan and
runtime cached.
* This may leave UNDEF arguments on the stack. To avoid having
to deal with them in other places, a CHECK_UNDEF_ARGS opcode
is used to either replace them with defaults, or error.
* For variadic functions, EX(extra_named_params) are collected
and need to be freed based on ZEND_CALL_HAS_EXTRA_NAMED_PARAMS.
RFC: https://wiki.php.net/rfc/named_params
Closes GH-5357.
While performing resource -> object migrations, we're adding
defensive classes that are final, non-serializable and non-clonable
(unless they are, of course). This path adds a ZEND_ACC_NO_DYNAMIC_PROPERTIES
flag, that also forbids the creation of dynamic properties on these objects.
This is a subset of #3931 and targeted at internal usage only
(though may be extended to userland at some point in the future).
It's already possible to achieve this (what the removed
WeakRef/WeakMap code does), but there's some caveats: First, this
simple approach is only possible if the class has no declared
properties, otherwise it's necessary to special-case those
properties. Second, it's easy to make it overly strict, e.g. by
forbidding isset($obj->prop) as well. And finally, it requires a
lot of boilerplate code for each class.
Closes GH-5572.
This is a bit tricky: In this cases we have "namespace as", which
means that we will only recognize "namespace" as an identifier when
the lookahead token is already at the "as". This means that
zend_lex_tstring picks up the wrong identifier.
We solve this by actually assigning the identifier as the semantic
value on the parser stack -- as in almost all cases we will not
actually need the identifier, this is just an (offset, size)
reference, not a copy of the string.
Additionally, we need to teach the lexer feedback mechanism used
by tokenizer TOKEN_PARSE mode to apply feedback to something
other than the very last token. To that purpose we pass through
the token text and check the tokens in reverse order to find the
right one.
Closes GH-5668.