PHP 7.3 INTERNALS UPGRADE NOTES

1. Internal API changes
  a. array_init() and array_init_size()
  b. Run-time constant operand addressing
  c. Array/Object recursion protection
  d. HASH_FLAG_PERSISTENT
  e. AST and IS_CONSTANT
  f. GC_REFCOUNT()
  g. zend_get_parameters()
  h. zend_register_persistent_resource()
  i. RAND_RANGE()
  j. cast_object() with _IS_NUMBER
  k. zend_fcall_info_cache.initialized
  l. php_hrtime_current()
  m. zend_cpu_supports()
  n. IS_TYPE_COPYABLE
  o. IS_UNUSED
  p. VM instruction operands (FETCH_CLASS, FETCH_CONSTANT, CATCH)
  q. sapi_cli_single_write()
  r. php_url
  s. zend_function.reserved[]
  t. zif_handler
  u. GC_G
  v. php_add[c]slashes
  w. zend_class_entry.iterator_funcs
  x. Class declaration opcodes (DECLARE_INHERITED_CLASS ...)
  y. zend_constant
  z. HAVE_ST_BLKSIZE and HAVE_ST_RDEV
  aa. RETSIGTYPE
  bb. php_setcookie

2. Build system changes
  a. Unix build system changes
  b. Windows build system changes


3. Module changes

========================
1. Internal API changes
========================

  a. array_init() and array_init_size() are not functions anymore.
     They don't return any values.

  b. In 64-bit builds PHP-7.2 and below used relative run-time constant operand
     addressing. E.g. opline->op1.constant kept an offset from start of literals
     table - op_array->literals. To speedup access op_array->literals was cached
     in execute_data->literals. So the resulting address calculated as
     EX(literals) + opline->op1.constant.

     Now at run-time literals allocated close to opcodes, and addressed
     relatively from current opline. This eliminates load of EX(literals) on
     each constant access as well as EX(literals) initialization on each call.

     As result some related macros were removed (ZEND_EX_USE_LITERALS,
     EX_LOAD_LITERALS, EX_LITERALS, RT_CONSTANT_EX, EX_CONSTANT) or changed
     (RT_CONSTANT, ZEND_PASS_TWO_UPDATE_CONSTANT, ZEND_PASS_TWO_UNDO_CONSTANT).
     This change may affect only some "system" extensions. EX_LITERALS,
     RT_CONSTANT_EX, EX_CONSTANT should be substituted by RT_CONSTANT, and now
     use "opline" (instead of "op_array") as first argument.

  c. Protection from recursion during processing circular data structures was
     refactored. HashTable.nApplyCount and IS_OBJ_APPLY_COUNT are replaced by
     single flag GC_PROTECTED. Corresponding macros Z_OBJ_APPLY_COUNT,
     Z_OBJ_INC_APPLY_COUNT, Z_OBJ_DEC_APPLY_COUNT, ZEND_HASH_GET_APPLY_COUNT,
     ZEND_HASH_INC_APPLY_COUNT, ZEND_HASH_DEC_APPLY_COUNT are replaced with
     GC_IS_RECURSIVE, GC_PROTECT_RECURSION, GC_UNPROTECT_RECURSION,
     Z_IS_RECURSIVE, Z_PROTECT_RECURSION, Z_UNPROTECT_RECURSION.

     HASH_FLAG_APPLY_PROTECTION flag and ZEND_HASH_APPLY_PROTECTION() macro
     are removed. All mutable arrays should use recursion protection.
     Corresponding checks should be replaced by Z_REFCOUNTED() or
     !(GC_FLAGS(p) & GC_IMMUTABLE).

  d. HASH_FLAG_PERSISTENT renamed into IS_ARRAY_PERSISTENT and moved into
     GC_FLAGS (to be consistent with IS_STR_PERSISTENT).

  e. zend_ast_ref structure is changed to use only one allocation.
     zend_ast_copy() now returns zend_ast_ref (instead of zend_asr).
     zend_ast_destroy_and_free() is removed. ZVAL_NEW_AST() is replaced
     by ZVAL_AST().

     IS_CONSTANT type and Z_CONST_FLAGS() are removed. Now constants are always
     represented using IS_CONSTANT_AST (ZEND_AST_CONSTANT kind). AST node
     attributes are used instead of constant flags. IS_TYPE_CONSTANT flag is
     removed, but Z_CONSTANT() macro is kept for compatibility.

  f. GC_REFCOUNT() is turned into inline function and can't be modified direcly.
     All reference-counting operations should be done through corresponding
     macros GC_SET_REFCOUNT(), GC_ADDREF() and GC_DELREF().

     GC_REFCOUNT(p)++ should be changed into GC_ADDREF(p),
     GC_REFCOUNT(p)-- into GC_DELREF(p),
     GC_REFCOUNT(p) = 1 into GC_SET_REFCOUNT(p, 1).

  g. The zend_get_parameters() and zend_get_parameters_ex() functions were
     removed. Instead zend_parse_parameters() should be used.

  h. New functions zend_register_persistent_resource() or
     zend_register_persistent_resource_ex() should beused to register
     persistent resources, instead of manual insertion into EG(persistent_list).

  i. The RAND_RANGE() macro has been removed. php_mt_rand_range() should be
     used instead.

  j. The cast_object() object handler now also accepts the _IS_NUMBER type. The
     handler should return either an integer or float value in this case,
     whichever is more appropriate.

  k. zend_fcall_info_cache.initialized is removed. zend_fcall_info_cache is
     initialized if zend_fcall_info_cache.function_handler is set.

  l. php_hrtime_current() delivers the number of nanoseconds since an uncertain
     point in the past.

  m. zend_cpu_supports() determines if a feature is supported by current cpu.
     Also serial inline zend_cpu_supports_xxx() are added, which is designed for
     ifunc resolver function, as resolver function should not depend on any
     external function.

  n. IS_TYPE_COPYABLE flag is removed. IS_STRING zvals didn't need to be
     duplication by zval_copy_ctor(), ZVAL_DUP() and SEPARATE_ZVAL*() macros.
     Interned strings didn't set IS_TYPE_COPYABLE, so they aren't affected at
     all. Now instead of checking for IS_TYPE_COPYABLE, engine checks for
     IS_ARRAY type (it may be IS_TYPE_REFCOUNTED or not). All the related
     macros: Z_COPYABLE..., Z_IMMUTABLE... are kept for compatibility.

  o. IS_UNUSED became zero and can't be used as a bitmask (there were no such
     usages in PHP sources).

  p. Operands of few VM instructions were changed
    - FETCH_CLASS     op1<fetch-flags>, op2<name>, result<var>
    - FETCH_CONSTANT  op1<fetch-flags>, op2<name>, result<tmp>
    - CATCH           ext<last-flag>, op1<name>, op2<jump_addr>, result<cv>

 q.  sapi_cli_single_write() now returns ssize_t instead of size_t.

 r.  fields of php_url struct change from char * to zend_string *

 s. Special purpose zend_functions marked by ZEND_ACC_CALL_VIA_TRAMPOLINE or
    ZEND_ACC_FAKE_CLOSURE flags use reserved[0] for internal purpose.
    Third party extensions must not modify reserved[] fields of these functions.

 t. For internal functions the typedef zif_handler has been introduced.  It is
    recommended to use this from now on, instead of defining own handler types.

 u. The GC globals (GC_G) are now private. Use the new zend_gc_get_status() to
    retrieve status information of the GC.

 v. The should_free argument of the php_add[c]slashes functions has been
    removed.  It is now always the caller's responsibility to free the passed
    string.

 w. zend_class_entry.iterator_funcs have been replaced by iterator_funcs_ptr.
    You don't have to set its value, setting parent.funcs in the get_iterator
    function is enough.

 x. Class declaration opcode formats were changed
  - DECLARE_INHERITED_CLASS and DECLARE_ANON_INHERITED_CLASS now encode parent
    class name in second operand directly (as IS_CONST operand). Previously,
    parent class was fetched by the prior FETCH_CLASS opcode.
  - ADD_INTERFACE and ADD_TRAIT don't use run-time cache to keep interface or
    trait. These instructions are executed once, and caching is useless.

 y. zend_constant.flags and zend_constant.module_number are packed into
    reserved space inside zend_constant.value. They should be accessed using
    ZEND_CONSTANT_FLAGS(), ZEND_CONSTANT_MODULE_NUMBER() and
    ZEND_CONSTANT_SET_FLAGS() macros.

 z. HAVE_ST_BLKSIZE must be replaced with HAVE_STRUCT_STAT_ST_BLKSIZE and
    HAVE_ST_RDEV must be replaced with HAVE_STRUCT_STAT_ST_RDEV.

 aa. RETSIGTYPE has been removed from the generated php_config.h and should be
    replaced with void.

 bb. php_setcookie() now expects an additional samesite argument, and the
    url_encode parameter has been moved to the end. The signature is now:
    int php_setcookie(zend_string *name, zend_string *value, time_t expires,
                      zend_string *path, zend_string *domain, int secure,
                      int httponly, zend_string *samesite, int url_encode);

========================
2. Build system changes
========================

  a. Unix build system changes
    - PHP_PROG_LEX, TSRM_CHECK_GCC_ARG, and LIBZEND_CPLUSPLUS_CHECKS Autoconf
      macros have been removed.
    - Minimum Autoconf version is 2.68+ for generating the configure script.

  b. Windows build system changes
    - ZEND_WIN32_FORCE_INLINE doesn't affect C++ anymore. zend_always_inline is
      still usable in C++, but anything else inlining related is up to
      compiler.
    - ZEND_WIN32_KEEP_INLINE was removed, it was only needed for C++
      convenience and is now default behavior with C++.
    - New configure option --enable-native-intrinsics accepts a list of the
      intrinsic optimizations to enable. It affects both the code generation
      and the explicit optimizations guarded by preprocessor macros.
    - The configure option --with-codegen-arch accepts only ia32 as a value.
      Use it, to produce builds suitable for older processors without SSE2 or
      even SSE support.

========================
3. Module changes
========================
