Add ZVAL_CHAR/RETVAL_CHAR/RETURN_CHAR as a shortcut for using
ZVAL_INTERNED_STRING and ZSTR_CHAR.
Add zend_string_init_fast() as a helper for the empty string /
one char interned string / zend_string_init() pattern.
Also add corresponding ZVAL_STRINGL_FAST etc macros.
Closes GH-5684.
RFC: https://wiki.php.net/rfc/static_return_type
The "static" type is represented as MAY_BE_STATIC, rather than
a class type like "self" and "parent", as it has special
resolution semantics, and cannot be cached in the runtime cache.
Closes GH-5062.
Instead of having a completely independent encoding for type list
entries. This is going to use more memory, but I'm not particularly
concerned about that, as type unions that contain multiple classes
should be uncommon. On the other hand, this allows us to treat
top-level types and types inside lists mostly the same.
A new ZEND_TYPE_FOREACH macros allows to transparently treat list
and non-list types the same way. I'm not using it everywhere it could be
used for now, just the places that seemed most obvious.
Of course, this will make any future type system changes much simpler,
as it will not be necessary to duplicate all logic two times.
Convert the empty string assignment to an Error as per RFC [1]
Add a warning that only the first byte will be assigned to the offset if provided
a needle that is longer than one byte.
[1] https://wiki.php.net/rfc/engine_warnings
According to RFC: https://wiki.php.net/rfc/union_types_v2
The type representation now makes use of both the pointer payload
and the type mask at the same time. Additionall, zend_type_list is
introduced as a new kind of pointer payload, which is used to store
multiple class types. Each of the class types is a tagged pointer,
which may be either a class name or class entry. The latter is only
used for typed properties, while arguments/returns will instead use
cache slots. A type list can contain a mix of both names and CEs at
the same time, as not all classes may be resolvable.
One thing this is missing is support for union types in arginfo
and stubs, which I want to handle separately.
I've also dropped the special object code from the JIT implementation
for now -- I plan to add this back in a different form at a later time.
For now I did not want to include non-trivial JIT changes together
with large functional changes.
Another possible piece of follow-up work is to implement "iterable"
as an internal alias for "array|Traversable". I believe this will
eliminate quite a few special-cases that had to be implemented.
Closes GH-4838.
We now store the pointer payload and the type mask separately. This
is in preparation for union types, where we will be using both at
the same time.
To avoid increasing the size of arginfo structures, the
pass_by_reference and is_variadic fields are now stored as part of
the type_mask (8-bit are reserved for custom use).
Different types of pointer payloads are distinguished based on bits
in the type_mask.
* Change a number of "resource used as offset" notices to warnings,
which were previously missed.
* Throw the "resource used as offset" warning for isset() as well.
* Make array_key_exists() behavior with regard to different key
types consistent with isset() and normal array accesses. All key
types now use the usual coercions and array/object keys throw
TypeError.
Closes GH-4887.
It is now only used to signal exceptions for property reads. ERROR
zvals are never returned back to the VM anymore, so there's no
need to check for them when receiving a VAR.
Also return MAY_BE_ERROR, as ERROR is now no longer relevant for
inference.
This switches zend_type from storing a single IS_* type code to
storing a MAY_BE_* type mask. Right now most code still assumes
that there is only a single type in the mask (or two together
with MAY_BE_NULL). But this will make it a lot simpler to introduce
union types.
An additional advantage (and why I'm doing this separately), is
that a number of special cases no longer need to be handled
separately: We can do a single mask & (1 << type) check to handle
all simple types, booleans (true|false) and null.
To avoid duplicate type checks. In debug builds arginfo is still
checked and will generate an assertions if the function doesn't
subsequently throw an exception.
Some test results change due to differences in zpp and arginfo
error messages.
Now that set() is gone, there is little point in keeping get(), as
it is essentially just a different way of writing cast_object()
now.
Closes GH-4202.