]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.4'
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 3 Feb 2020 12:41:45 +0000 (13:41 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 3 Feb 2020 12:42:08 +0000 (13:42 +0100)
* PHP-7.4:
  Apply tidy formatting

20 files changed:
1  2 
Zend/zend.c
Zend/zend_execute.c
Zend/zend_vm_gen.php
ext/ext_skel.php
ext/ffi/ffi.stub.php
ext/pdo_firebird/firebird_statement.c
ext/pdo_firebird/pdo_firebird.c
ext/pdo_sqlite/sqlite_statement.c
ext/phar/phar_object.stub.php
ext/snmp/snmp.stub.php
main/php_variables.c
run-tests.php
sapi/cli/generate_mime_type_map.php
sapi/phpdbg/create-test.php
sapi/phpdbg/phpdbg_bp.c
scripts/dev/check_parameters.php
scripts/dev/search_underscores.php
win32/build/mkdist.php
win32/ioutil.c
win32/winutil.c

diff --cc Zend/zend.c
index 20e7e85acc94cfa46a56e19b37b564f057928fb7,97ac3327cab0204af444387b92b8f201bfcc15dc..9f3c05f97324893ec18e93229cee1b91b9277e5e
@@@ -962,15 -952,6 +962,15 @@@ void zend_register_standard_ini_entries
  }
  /* }}} */
  
- static zend_class_entry *resolve_type_name(zend_string *type_name) { 
++static zend_class_entry *resolve_type_name(zend_string *type_name) {
 +      zend_string *lc_type_name = zend_string_tolower(type_name);
 +      zend_class_entry *ce = zend_hash_find_ptr(CG(class_table), lc_type_name);
 +
 +      ZEND_ASSERT(ce && ce->type == ZEND_INTERNAL_CLASS);
 +      zend_string_release(lc_type_name);
 +      return ce;
 +}
 +
  static void zend_resolve_property_types(void) /* {{{ */
  {
        zend_class_entry *ce;
index 9203fa6eb567a92dc0a7211c30558a4a3fb8c51a,de00080b5a988c99d784976cdd3884c382a6abdb..18fb8e9aba8affee97bf68fe381a31a767b18de1
@@@ -1597,18 -1578,14 +1597,18 @@@ static zend_never_inline void zend_assi
                string_len = Z_STRLEN_P(value);
                c = (zend_uchar)Z_STRVAL_P(value)[0];
        }
-       
 -      if (string_len == 0) {
 -              /* Error on empty input string */
 -              zend_error(E_WARNING, "Cannot assign an empty string to a string offset");
 -              if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 -                      ZVAL_NULL(EX_VAR(opline->result.var));
 +      if (string_len != 1) {
 +              if (string_len == 0) {
 +                      /* Error on empty input string */
 +                      zend_throw_error(NULL, "Cannot assign an empty string to a string offset");
 +                      if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
 +                              ZVAL_NULL(EX_VAR(opline->result.var));
 +                      }
 +                      return;
                }
 -              return;
 +
 +              zend_error(E_WARNING, "Only the first byte will be assigned to the string offset");
        }
  
        if (offset < 0) { /* Handle negative offset */
index ccf23613f73d0164e24afda5802a2774ebeb4d7a,22586cbd0b44705eb3fa053a9002e91e51ac454d..7210bb2f20722d4cbee961a9c0f3cd9866d5b47d
@@@ -55,44 -55,44 +55,44 @@@ const ZEND_VM_KIND_GOTO   = 3
  const ZEND_VM_KIND_HYBRID = 4;
  
  $vm_op_flags = array(
-       "ZEND_VM_OP_SPEC"         => 1<<0,
-       "ZEND_VM_OP_CONST"        => 1<<1,
-       "ZEND_VM_OP_TMPVAR"       => 1<<2,
-       "ZEND_VM_OP_TMPVARCV"     => 1<<3,
-       "ZEND_VM_OP_MASK"         => 0xf0,
-       "ZEND_VM_OP_NUM"          => 0x10,
-       "ZEND_VM_OP_JMP_ADDR"     => 0x20,
-       "ZEND_VM_OP_TRY_CATCH"    => 0x30,
-       // unused 0x40
-       "ZEND_VM_OP_THIS"         => 0x50,
-       "ZEND_VM_OP_NEXT"         => 0x60,
-       "ZEND_VM_OP_CLASS_FETCH"  => 0x70,
-       "ZEND_VM_OP_CONSTRUCTOR"  => 0x80,
-       "ZEND_VM_OP_CONST_FETCH"  => 0x90,
-       "ZEND_VM_OP_CACHE_SLOT"   => 0xa0,
-       "ZEND_VM_EXT_VAR_FETCH"   => 1<<16,
-       "ZEND_VM_EXT_ISSET"       => 1<<17,
-       "ZEND_VM_EXT_CACHE_SLOT"  => 1<<18,
-       "ZEND_VM_EXT_ARRAY_INIT"  => 1<<19,
-       "ZEND_VM_EXT_REF"         => 1<<20,
-       "ZEND_VM_EXT_FETCH_REF"   => 1<<21,
-       "ZEND_VM_EXT_DIM_WRITE"    => 1<<22,
-       "ZEND_VM_EXT_MASK"        => 0x0f000000,
-       "ZEND_VM_EXT_NUM"         => 0x01000000,
-       "ZEND_VM_EXT_LAST_CATCH"  => 0x02000000,
-       "ZEND_VM_EXT_JMP_ADDR"    => 0x03000000,
-       "ZEND_VM_EXT_OP"          => 0x04000000,
+     "ZEND_VM_OP_SPEC"         => 1<<0,
+     "ZEND_VM_OP_CONST"        => 1<<1,
+     "ZEND_VM_OP_TMPVAR"       => 1<<2,
+     "ZEND_VM_OP_TMPVARCV"     => 1<<3,
+     "ZEND_VM_OP_MASK"         => 0xf0,
+     "ZEND_VM_OP_NUM"          => 0x10,
+     "ZEND_VM_OP_JMP_ADDR"     => 0x20,
+     "ZEND_VM_OP_TRY_CATCH"    => 0x30,
+     // unused 0x40
+     "ZEND_VM_OP_THIS"         => 0x50,
+     "ZEND_VM_OP_NEXT"         => 0x60,
+     "ZEND_VM_OP_CLASS_FETCH"  => 0x70,
+     "ZEND_VM_OP_CONSTRUCTOR"  => 0x80,
+     "ZEND_VM_OP_CONST_FETCH"  => 0x90,
+     "ZEND_VM_OP_CACHE_SLOT"   => 0xa0,
+     "ZEND_VM_EXT_VAR_FETCH"   => 1<<16,
+     "ZEND_VM_EXT_ISSET"       => 1<<17,
+     "ZEND_VM_EXT_CACHE_SLOT"  => 1<<18,
+     "ZEND_VM_EXT_ARRAY_INIT"  => 1<<19,
+     "ZEND_VM_EXT_REF"         => 1<<20,
+     "ZEND_VM_EXT_FETCH_REF"   => 1<<21,
 -    "ZEND_VM_EXT_DIM_OBJ_WRITE" => 1<<22,
++    "ZEND_VM_EXT_DIM_WRITE"    => 1<<22,
+     "ZEND_VM_EXT_MASK"        => 0x0f000000,
+     "ZEND_VM_EXT_NUM"         => 0x01000000,
+     "ZEND_VM_EXT_LAST_CATCH"  => 0x02000000,
+     "ZEND_VM_EXT_JMP_ADDR"    => 0x03000000,
+     "ZEND_VM_EXT_OP"          => 0x04000000,
      // unused 0x5000000
      // unused 0x6000000
-       "ZEND_VM_EXT_TYPE"        => 0x07000000,
-       "ZEND_VM_EXT_EVAL"        => 0x08000000,
-       "ZEND_VM_EXT_TYPE_MASK"   => 0x09000000,
-       // unused 0x0a000000,
-       "ZEND_VM_EXT_SRC"         => 0x0b000000,
-       // unused 0x0c000000,
-       "ZEND_VM_NO_CONST_CONST"  => 0x40000000,
-       "ZEND_VM_COMMUTATIVE"     => 0x80000000,
+     "ZEND_VM_EXT_TYPE"        => 0x07000000,
+     "ZEND_VM_EXT_EVAL"        => 0x08000000,
+     "ZEND_VM_EXT_TYPE_MASK"   => 0x09000000,
+     // unused 0x0a000000,
+     "ZEND_VM_EXT_SRC"         => 0x0b000000,
+     // unused 0x0c000000,
+     "ZEND_VM_NO_CONST_CONST"  => 0x40000000,
+     "ZEND_VM_COMMUTATIVE"     => 0x80000000,
  );
  
  foreach ($vm_op_flags as $name => $val) {
@@@ -120,21 -120,21 +120,21 @@@ $vm_op_decode = array
  );
  
  $vm_ext_decode = array(
-       "NUM"                  => ZEND_VM_EXT_NUM,
-       "LAST_CATCH"           => ZEND_VM_EXT_LAST_CATCH,
-       "JMP_ADDR"             => ZEND_VM_EXT_JMP_ADDR,
-       "OP"                   => ZEND_VM_EXT_OP,
-       "VAR_FETCH"            => ZEND_VM_EXT_VAR_FETCH,
-       "ARRAY_INIT"           => ZEND_VM_EXT_ARRAY_INIT,
-       "TYPE"                 => ZEND_VM_EXT_TYPE,
-       "EVAL"                 => ZEND_VM_EXT_EVAL,
-       "TYPE_MASK"            => ZEND_VM_EXT_TYPE_MASK,
-       "ISSET"                => ZEND_VM_EXT_ISSET,
-       "REF"                  => ZEND_VM_EXT_REF,
-       "FETCH_REF"            => ZEND_VM_EXT_FETCH_REF,
-       "SRC"                  => ZEND_VM_EXT_SRC,
-       "CACHE_SLOT"           => ZEND_VM_EXT_CACHE_SLOT,
-       "DIM_WRITE"            => ZEND_VM_EXT_DIM_WRITE,
+     "NUM"                  => ZEND_VM_EXT_NUM,
+     "LAST_CATCH"           => ZEND_VM_EXT_LAST_CATCH,
+     "JMP_ADDR"             => ZEND_VM_EXT_JMP_ADDR,
+     "OP"                   => ZEND_VM_EXT_OP,
+     "VAR_FETCH"            => ZEND_VM_EXT_VAR_FETCH,
+     "ARRAY_INIT"           => ZEND_VM_EXT_ARRAY_INIT,
+     "TYPE"                 => ZEND_VM_EXT_TYPE,
+     "EVAL"                 => ZEND_VM_EXT_EVAL,
+     "TYPE_MASK"            => ZEND_VM_EXT_TYPE_MASK,
+     "ISSET"                => ZEND_VM_EXT_ISSET,
+     "REF"                  => ZEND_VM_EXT_REF,
+     "FETCH_REF"            => ZEND_VM_EXT_FETCH_REF,
+     "SRC"                  => ZEND_VM_EXT_SRC,
+     "CACHE_SLOT"           => ZEND_VM_EXT_CACHE_SLOT,
 -    "DIM_OBJ_WRITE"        => ZEND_VM_EXT_DIM_OBJ_WRITE,
++    "DIM_WRITE"            => ZEND_VM_EXT_DIM_WRITE,
  );
  
  $vm_kind_name = array(
@@@ -198,300 -198,322 +198,300 @@@ $op1_type = array
  );
  
  $op2_type = array(
-       "ANY"      => "opline->op2_type",
-       "TMP"      => "IS_TMP_VAR",
-       "VAR"      => "IS_VAR",
-       "CONST"    => "IS_CONST",
-       "UNUSED"   => "IS_UNUSED",
-       "CV"       => "IS_CV",
-       "TMPVAR"   => "(IS_TMP_VAR|IS_VAR)",
-       "TMPVARCV" => "(IS_TMP_VAR|IS_VAR|IS_CV)",
+     "ANY"      => "opline->op2_type",
+     "TMP"      => "IS_TMP_VAR",
+     "VAR"      => "IS_VAR",
+     "CONST"    => "IS_CONST",
+     "UNUSED"   => "IS_UNUSED",
+     "CV"       => "IS_CV",
+     "TMPVAR"   => "(IS_TMP_VAR|IS_VAR)",
+     "TMPVARCV" => "(IS_TMP_VAR|IS_VAR|IS_CV)",
  );
  
 -$op1_free = array(
 -    "ANY"      => "(free_op1 != NULL)",
 -    "TMP"      => "1",
 -    "VAR"      => "(free_op1 != NULL)",
 -    "CONST"    => "0",
 -    "UNUSED"   => "0",
 -    "CV"       => "0",
 -    "TMPVAR"   => "???",
 -    "TMPVARCV" => "???",
 -);
 -
 -$op2_free = array(
 -    "ANY"      => "(free_op2 != NULL)",
 -    "TMP"      => "1",
 -    "VAR"      => "(free_op2 != NULL)",
 -    "CONST"    => "0",
 -    "UNUSED"   => "0",
 -    "CV"       => "0",
 -    "TMPVAR"   => "???",
 -    "TMPVARCV" => "???",
 -);
 -
  $op1_get_zval_ptr = array(
-       "ANY"      => "get_zval_ptr(opline->op1_type, opline->op1, \\1)",
-       "TMP"      => "_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC)",
-       "VAR"      => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
-       "CONST"    => "RT_CONSTANT(opline, opline->op1)",
-       "UNUSED"   => "NULL",
-       "CV"       => "_get_zval_ptr_cv_\\1(opline->op1.var EXECUTE_DATA_CC)",
-       "TMPVAR"   => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_zval_ptr(opline->op1_type, opline->op1, &free_op1, \\1)",
 -    "TMP"      => "_get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
 -    "VAR"      => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
++    "ANY"      => "get_zval_ptr(opline->op1_type, opline->op1, \\1)",
++    "TMP"      => "_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
+     "CONST"    => "RT_CONSTANT(opline, opline->op1)",
+     "UNUSED"   => "NULL",
+     "CV"       => "_get_zval_ptr_cv_\\1(opline->op1.var EXECUTE_DATA_CC)",
 -    "TMPVAR"   => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
++    "TMPVAR"   => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
+     "TMPVARCV" => "???",
  );
  
  $op2_get_zval_ptr = array(
-       "ANY"      => "get_zval_ptr(opline->op2_type, opline->op2, \\1)",
-       "TMP"      => "_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)",
-       "VAR"      => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
-       "CONST"    => "RT_CONSTANT(opline, opline->op2)",
-       "UNUSED"   => "NULL",
-       "CV"       => "_get_zval_ptr_cv_\\1(opline->op2.var EXECUTE_DATA_CC)",
-       "TMPVAR"   => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_zval_ptr(opline->op2_type, opline->op2, &free_op2, \\1)",
 -    "TMP"      => "_get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
 -    "VAR"      => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
++    "ANY"      => "get_zval_ptr(opline->op2_type, opline->op2, \\1)",
++    "TMP"      => "_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
+     "CONST"    => "RT_CONSTANT(opline, opline->op2)",
+     "UNUSED"   => "NULL",
+     "CV"       => "_get_zval_ptr_cv_\\1(opline->op2.var EXECUTE_DATA_CC)",
 -    "TMPVAR"   => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
++    "TMPVAR"   => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
+     "TMPVARCV" => "???",
  );
  
  $op1_get_zval_ptr_ptr = array(
-       "ANY"      => "get_zval_ptr_ptr(opline->op1_type, opline->op1, \\1)",
-       "TMP"      => "NULL",
-       "VAR"      => "_get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
-       "CONST"    => "NULL",
-       "UNUSED"   => "NULL",
-       "CV"       => "_get_zval_ptr_cv_\\1(opline->op1.var EXECUTE_DATA_CC)",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_zval_ptr_ptr(opline->op1_type, opline->op1, &free_op1, \\1)",
++    "ANY"      => "get_zval_ptr_ptr(opline->op1_type, opline->op1, \\1)",
+     "TMP"      => "NULL",
 -    "VAR"      => "_get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
+     "CONST"    => "NULL",
+     "UNUSED"   => "NULL",
+     "CV"       => "_get_zval_ptr_cv_\\1(opline->op1.var EXECUTE_DATA_CC)",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op2_get_zval_ptr_ptr = array(
-       "ANY"      => "get_zval_ptr_ptr(opline->op2_type, opline->op2, \\1)",
-       "TMP"      => "NULL",
-       "VAR"      => "_get_zval_ptr_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
-       "CONST"    => "NULL",
-       "UNUSED"   => "NULL",
-       "CV"       => "_get_zval_ptr_cv_\\1(opline->op2.var EXECUTE_DATA_CC)",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_zval_ptr_ptr(opline->op2_type, opline->op2, &free_op2, \\1)",
++    "ANY"      => "get_zval_ptr_ptr(opline->op2_type, opline->op2, \\1)",
+     "TMP"      => "NULL",
 -    "VAR"      => "_get_zval_ptr_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
+     "CONST"    => "NULL",
+     "UNUSED"   => "NULL",
+     "CV"       => "_get_zval_ptr_cv_\\1(opline->op2.var EXECUTE_DATA_CC)",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op1_get_zval_ptr_deref = array(
-       "ANY"      => "get_zval_ptr_deref(opline->op1_type, opline->op1, \\1)",
-       "TMP"      => "_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC)",
-       "VAR"      => "_get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC)",
-       "CONST"    => "RT_CONSTANT(opline, opline->op1)",
-       "UNUSED"   => "NULL",
-       "CV"       => "_get_zval_ptr_cv_deref_\\1(opline->op1.var EXECUTE_DATA_CC)",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_zval_ptr_deref(opline->op1_type, opline->op1, &free_op1, \\1)",
 -    "TMP"      => "_get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
 -    "VAR"      => "_get_zval_ptr_var_deref(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
++    "ANY"      => "get_zval_ptr_deref(opline->op1_type, opline->op1, \\1)",
++    "TMP"      => "_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC)",
+     "CONST"    => "RT_CONSTANT(opline, opline->op1)",
+     "UNUSED"   => "NULL",
+     "CV"       => "_get_zval_ptr_cv_deref_\\1(opline->op1.var EXECUTE_DATA_CC)",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op2_get_zval_ptr_deref = array(
-       "ANY"      => "get_zval_ptr_deref(opline->op2_type, opline->op2, \\1)",
-       "TMP"      => "_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)",
-       "VAR"      => "_get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC)",
-       "CONST"    => "RT_CONSTANT(opline, opline->op2)",
-       "UNUSED"   => "NULL",
-       "CV"       => "_get_zval_ptr_cv_deref_\\1(opline->op2.var EXECUTE_DATA_CC)",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_zval_ptr_deref(opline->op2_type, opline->op2, &free_op2, \\1)",
 -    "TMP"      => "_get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
 -    "VAR"      => "_get_zval_ptr_var_deref(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
++    "ANY"      => "get_zval_ptr_deref(opline->op2_type, opline->op2, \\1)",
++    "TMP"      => "_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC)",
+     "CONST"    => "RT_CONSTANT(opline, opline->op2)",
+     "UNUSED"   => "NULL",
+     "CV"       => "_get_zval_ptr_cv_deref_\\1(opline->op2.var EXECUTE_DATA_CC)",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op1_get_zval_ptr_undef = array(
-       "ANY"      => "get_zval_ptr_undef(opline->op1_type, opline->op1, \\1)",
-       "TMP"      => "_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC)",
-       "VAR"      => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
-       "CONST"    => "RT_CONSTANT(opline, opline->op1)",
-       "UNUSED"   => "NULL",
-       "CV"       => "EX_VAR(opline->op1.var)",
-       "TMPVAR"   => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
-       "TMPVARCV" => "EX_VAR(opline->op1.var)",
 -    "ANY"      => "get_zval_ptr_undef(opline->op1_type, opline->op1, &free_op1, \\1)",
 -    "TMP"      => "_get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
 -    "VAR"      => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
++    "ANY"      => "get_zval_ptr_undef(opline->op1_type, opline->op1, \\1)",
++    "TMP"      => "_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
+     "CONST"    => "RT_CONSTANT(opline, opline->op1)",
+     "UNUSED"   => "NULL",
+     "CV"       => "EX_VAR(opline->op1.var)",
 -    "TMPVAR"   => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
++    "TMPVAR"   => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
+     "TMPVARCV" => "EX_VAR(opline->op1.var)",
  );
  
  $op2_get_zval_ptr_undef = array(
-       "ANY"      => "get_zval_ptr_undef(opline->op2_type, opline->op2, \\1)",
-       "TMP"      => "_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)",
-       "VAR"      => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
-       "CONST"    => "RT_CONSTANT(opline, opline->op2)",
-       "UNUSED"   => "NULL",
-       "CV"       => "EX_VAR(opline->op2.var)",
-       "TMPVAR"   => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
-       "TMPVARCV" => "EX_VAR(opline->op2.var)",
 -    "ANY"      => "get_zval_ptr_undef(opline->op2_type, opline->op2, &free_op2, \\1)",
 -    "TMP"      => "_get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
 -    "VAR"      => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
++    "ANY"      => "get_zval_ptr_undef(opline->op2_type, opline->op2, \\1)",
++    "TMP"      => "_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
+     "CONST"    => "RT_CONSTANT(opline, opline->op2)",
+     "UNUSED"   => "NULL",
+     "CV"       => "EX_VAR(opline->op2.var)",
 -    "TMPVAR"   => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
++    "TMPVAR"   => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
+     "TMPVARCV" => "EX_VAR(opline->op2.var)",
  );
  
  $op1_get_zval_ptr_ptr_undef = array(
-       "ANY"      => "get_zval_ptr_ptr_undef(opline->op1_type, opline->op1, \\1)",
-       "TMP"      => "NULL",
-       "VAR"      => "_get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
-       "CONST"    => "NULL",
-       "UNUSED"   => "NULL",
-       "CV"       => "EX_VAR(opline->op1.var)",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_zval_ptr_ptr_undef(opline->op1_type, opline->op1, &free_op1, \\1)",
++    "ANY"      => "get_zval_ptr_ptr_undef(opline->op1_type, opline->op1, \\1)",
+     "TMP"      => "NULL",
 -    "VAR"      => "_get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
+     "CONST"    => "NULL",
+     "UNUSED"   => "NULL",
+     "CV"       => "EX_VAR(opline->op1.var)",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op2_get_zval_ptr_ptr_undef = array(
-       "ANY"      => "get_zval_ptr_ptr_undef(opline->op2_type, opline->op2, \\1)",
-       "TMP"      => "NULL",
-       "VAR"      => "_get_zval_ptr_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
-       "CONST"    => "NULL",
-       "UNUSED"   => "NULL",
-       "CV"       => "EX_VAR(opline->op2.var)",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_zval_ptr_ptr_undef(opline->op2_type, opline->op2, &free_op2, \\1)",
++    "ANY"      => "get_zval_ptr_ptr_undef(opline->op2_type, opline->op2, \\1)",
+     "TMP"      => "NULL",
 -    "VAR"      => "_get_zval_ptr_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
+     "CONST"    => "NULL",
+     "UNUSED"   => "NULL",
+     "CV"       => "EX_VAR(opline->op2.var)",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op1_get_obj_zval_ptr = array(
-       "ANY"      => "get_obj_zval_ptr(opline->op1_type, opline->op1, \\1)",
-       "TMP"      => "_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC)",
-       "VAR"      => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
-       "CONST"    => "RT_CONSTANT(opline, opline->op1)",
-       "UNUSED"   => "&EX(This)",
-       "CV"       => "_get_zval_ptr_cv_\\1(opline->op1.var EXECUTE_DATA_CC)",
-       "TMPVAR"   => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_obj_zval_ptr(opline->op1_type, opline->op1, &free_op1, \\1)",
 -    "TMP"      => "_get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
 -    "VAR"      => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
++    "ANY"      => "get_obj_zval_ptr(opline->op1_type, opline->op1, \\1)",
++    "TMP"      => "_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
+     "CONST"    => "RT_CONSTANT(opline, opline->op1)",
+     "UNUSED"   => "&EX(This)",
+     "CV"       => "_get_zval_ptr_cv_\\1(opline->op1.var EXECUTE_DATA_CC)",
 -    "TMPVAR"   => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
++    "TMPVAR"   => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
+     "TMPVARCV" => "???",
  );
  
  $op2_get_obj_zval_ptr = array(
-       "ANY"      => "get_obj_zval_ptr(opline->op2_type, opline->op2, \\1)",
-       "TMP"      => "_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)",
-       "VAR"      => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
-       "CONST"    => "RT_CONSTANT(opline, opline->op2)",
-       "UNUSED"   => "&EX(This)",
-       "CV"       => "_get_zval_ptr_cv_\\1(opline->op2.var EXECUTE_DATA_CC)",
-       "TMPVAR"   => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_obj_zval_ptr(opline->op2_type, opline->op2, &free_op2, \\1)",
 -    "TMP"      => "_get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
 -    "VAR"      => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
++    "ANY"      => "get_obj_zval_ptr(opline->op2_type, opline->op2, \\1)",
++    "TMP"      => "_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
+     "CONST"    => "RT_CONSTANT(opline, opline->op2)",
+     "UNUSED"   => "&EX(This)",
+     "CV"       => "_get_zval_ptr_cv_\\1(opline->op2.var EXECUTE_DATA_CC)",
 -    "TMPVAR"   => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
++    "TMPVAR"   => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
+     "TMPVARCV" => "???",
  );
  
  $op1_get_obj_zval_ptr_undef = array(
-       "ANY"      => "get_obj_zval_ptr_undef(opline->op1_type, opline->op1, \\1)",
-       "TMP"      => "_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC)",
-       "VAR"      => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
-       "CONST"    => "RT_CONSTANT(opline, opline->op1)",
-       "UNUSED"   => "&EX(This)",
-       "CV"       => "EX_VAR(opline->op1.var)",
-       "TMPVAR"   => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
-       "TMPVARCV" => "EX_VAR(opline->op1.var)",
 -    "ANY"      => "get_obj_zval_ptr_undef(opline->op1_type, opline->op1, &free_op1, \\1)",
 -    "TMP"      => "_get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
 -    "VAR"      => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
++    "ANY"      => "get_obj_zval_ptr_undef(opline->op1_type, opline->op1, \\1)",
++    "TMP"      => "_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
+     "CONST"    => "RT_CONSTANT(opline, opline->op1)",
+     "UNUSED"   => "&EX(This)",
+     "CV"       => "EX_VAR(opline->op1.var)",
 -    "TMPVAR"   => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
++    "TMPVAR"   => "_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
+     "TMPVARCV" => "EX_VAR(opline->op1.var)",
  );
  
  $op2_get_obj_zval_ptr_undef = array(
-       "ANY"      => "get_obj_zval_ptr_undef(opline->op2_type, opline->op2, \\1)",
-       "TMP"      => "_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)",
-       "VAR"      => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
-       "CONST"    => "RT_CONSTANT(opline, opline->op2)",
-       "UNUSED"   => "&EX(This)",
-       "CV"       => "EX_VAR(opline->op2.var)",
-       "TMPVAR"   => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
-       "TMPVARCV" => "EX_VAR(opline->op2.var)",
 -    "ANY"      => "get_obj_zval_ptr_undef(opline->op2_type, opline->op2, &free_op2, \\1)",
 -    "TMP"      => "_get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
 -    "VAR"      => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
++    "ANY"      => "get_obj_zval_ptr_undef(opline->op2_type, opline->op2, \\1)",
++    "TMP"      => "_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
+     "CONST"    => "RT_CONSTANT(opline, opline->op2)",
+     "UNUSED"   => "&EX(This)",
+     "CV"       => "EX_VAR(opline->op2.var)",
 -    "TMPVAR"   => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
++    "TMPVAR"   => "_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
+     "TMPVARCV" => "EX_VAR(opline->op2.var)",
  );
  
  $op1_get_obj_zval_ptr_deref = array(
-       "ANY"      => "get_obj_zval_ptr(opline->op1_type, opline->op1, \\1)",
-       "TMP"      => "_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC)",
-       "VAR"      => "_get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC)",
-       "CONST"    => "RT_CONSTANT(opline, opline->op1)",
-       "UNUSED"   => "&EX(This)",
-       "CV"       => "_get_zval_ptr_cv_deref_\\1(opline->op1.var EXECUTE_DATA_CC)",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_obj_zval_ptr(opline->op1_type, opline->op1, &free_op1, \\1)",
 -    "TMP"      => "_get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
 -    "VAR"      => "_get_zval_ptr_var_deref(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
++    "ANY"      => "get_obj_zval_ptr(opline->op1_type, opline->op1, \\1)",
++    "TMP"      => "_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC)",
+     "CONST"    => "RT_CONSTANT(opline, opline->op1)",
+     "UNUSED"   => "&EX(This)",
+     "CV"       => "_get_zval_ptr_cv_deref_\\1(opline->op1.var EXECUTE_DATA_CC)",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op2_get_obj_zval_ptr_deref = array(
-       "ANY"      => "get_obj_zval_ptr(opline->op2_type, opline->op2, \\1)",
-       "TMP"      => "_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)",
-       "VAR"      => "_get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC)",
-       "CONST"    => "RT_CONSTANT(opline, opline->op2)",
-       "UNUSED"   => "&EX(This)",
-       "CV"       => "_get_zval_ptr_cv_deref_\\1(opline->op2.var EXECUTE_DATA_CC)",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_obj_zval_ptr(opline->op2_type, opline->op2, &free_op2, \\1)",
 -    "TMP"      => "_get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
 -    "VAR"      => "_get_zval_ptr_var_deref(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
++    "ANY"      => "get_obj_zval_ptr(opline->op2_type, opline->op2, \\1)",
++    "TMP"      => "_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC)",
+     "CONST"    => "RT_CONSTANT(opline, opline->op2)",
+     "UNUSED"   => "&EX(This)",
+     "CV"       => "_get_zval_ptr_cv_deref_\\1(opline->op2.var EXECUTE_DATA_CC)",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op1_get_obj_zval_ptr_ptr = array(
-       "ANY"      => "get_obj_zval_ptr_ptr(opline->op1_type, opline->op1, \\1)",
-       "TMP"      => "NULL",
-       "VAR"      => "_get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
-       "CONST"    => "NULL",
-       "UNUSED"   => "&EX(This)",
-       "CV"       => "_get_zval_ptr_cv_\\1(opline->op1.var EXECUTE_DATA_CC)",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_obj_zval_ptr_ptr(opline->op1_type, opline->op1, &free_op1, \\1)",
++    "ANY"      => "get_obj_zval_ptr_ptr(opline->op1_type, opline->op1, \\1)",
+     "TMP"      => "NULL",
 -    "VAR"      => "_get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
+     "CONST"    => "NULL",
+     "UNUSED"   => "&EX(This)",
+     "CV"       => "_get_zval_ptr_cv_\\1(opline->op1.var EXECUTE_DATA_CC)",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op2_get_obj_zval_ptr_ptr = array(
-       "ANY"      => "get_obj_zval_ptr_ptr(opline->op2_type, opline->op2, \\1)",
-       "TMP"      => "NULL",
-       "VAR"      => "_get_zval_ptr_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
-       "CONST"    => "NULL",
-       "UNUSED"   => "&EX(This)",
-       "CV"       => "_get_zval_ptr_cv_\\1(opline->op2.var EXECUTE_DATA_CC)",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_obj_zval_ptr_ptr(opline->op2_type, opline->op2, &free_op2, \\1)",
++    "ANY"      => "get_obj_zval_ptr_ptr(opline->op2_type, opline->op2, \\1)",
+     "TMP"      => "NULL",
 -    "VAR"      => "_get_zval_ptr_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
+     "CONST"    => "NULL",
+     "UNUSED"   => "&EX(This)",
+     "CV"       => "_get_zval_ptr_cv_\\1(opline->op2.var EXECUTE_DATA_CC)",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op1_get_obj_zval_ptr_ptr_undef = array(
-       "ANY"      => "get_obj_zval_ptr_ptr(opline->op1_type, opline->op1, \\1)",
-       "TMP"      => "NULL",
-       "VAR"      => "_get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
-       "CONST"    => "NULL",
-       "UNUSED"   => "&EX(This)",
-       "CV"       => "EX_VAR(opline->op1.var)",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_obj_zval_ptr_ptr(opline->op1_type, opline->op1, &free_op1, \\1)",
++    "ANY"      => "get_obj_zval_ptr_ptr(opline->op1_type, opline->op1, \\1)",
+     "TMP"      => "NULL",
 -    "VAR"      => "_get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC)",
+     "CONST"    => "NULL",
+     "UNUSED"   => "&EX(This)",
+     "CV"       => "EX_VAR(opline->op1.var)",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op2_get_obj_zval_ptr_ptr_undef = array(
-       "ANY"      => "get_obj_zval_ptr_ptr(opline->op2_type, opline->op2, \\1)",
-       "TMP"      => "NULL",
-       "VAR"      => "_get_zval_ptr_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
-       "CONST"    => "NULL",
-       "UNUSED"   => "&EX(This)",
-       "CV"       => "EX_VAR(opline->op2.var)",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_obj_zval_ptr_ptr(opline->op2_type, opline->op2, &free_op2, \\1)",
++    "ANY"      => "get_obj_zval_ptr_ptr(opline->op2_type, opline->op2, \\1)",
+     "TMP"      => "NULL",
 -    "VAR"      => "_get_zval_ptr_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_ptr_var(opline->op2.var EXECUTE_DATA_CC)",
+     "CONST"    => "NULL",
+     "UNUSED"   => "&EX(This)",
+     "CV"       => "EX_VAR(opline->op2.var)",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op1_free_op = array(
-       "ANY"      => "FREE_OP(opline->op1_type, opline->op1.var)",
-       "TMP"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))",
-       "VAR"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))",
-       "CONST"    => "",
-       "UNUSED"   => "",
-       "CV"       => "",
-       "TMPVAR"   => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))",
-       "TMPVARCV" => "???",
 -    "ANY"      => "FREE_OP(free_op1)",
 -    "TMP"      => "zval_ptr_dtor_nogc(free_op1)",
 -    "VAR"      => "zval_ptr_dtor_nogc(free_op1)",
++    "ANY"      => "FREE_OP(opline->op1_type, opline->op1.var)",
++    "TMP"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))",
++    "VAR"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))",
+     "CONST"    => "",
+     "UNUSED"   => "",
+     "CV"       => "",
 -    "TMPVAR"   => "zval_ptr_dtor_nogc(free_op1)",
++    "TMPVAR"   => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))",
+     "TMPVARCV" => "???",
  );
  
  $op2_free_op = array(
-       "ANY"      => "FREE_OP(opline->op2_type, opline->op2.var)",
-       "TMP"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))",
-       "VAR"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))",
-       "CONST"    => "",
-       "UNUSED"   => "",
-       "CV"       => "",
-       "TMPVAR"   => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))",
-       "TMPVARCV" => "???",
 -    "ANY"      => "FREE_OP(free_op2)",
 -    "TMP"      => "zval_ptr_dtor_nogc(free_op2)",
 -    "VAR"      => "zval_ptr_dtor_nogc(free_op2)",
++    "ANY"      => "FREE_OP(opline->op2_type, opline->op2.var)",
++    "TMP"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))",
++    "VAR"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))",
+     "CONST"    => "",
+     "UNUSED"   => "",
+     "CV"       => "",
 -    "TMPVAR"   => "zval_ptr_dtor_nogc(free_op2)",
++    "TMPVAR"   => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))",
+     "TMPVARCV" => "???",
  );
  
  $op1_free_op_if_var = array(
-       "ANY"      => "if (opline->op1_type == IS_VAR) {zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));}",
-       "TMP"      => "",
-       "VAR"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))",
-       "CONST"    => "",
-       "UNUSED"   => "",
-       "CV"       => "",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "if (opline->op1_type == IS_VAR) {zval_ptr_dtor_nogc(free_op1);}",
++    "ANY"      => "if (opline->op1_type == IS_VAR) {zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));}",
+     "TMP"      => "",
 -    "VAR"      => "zval_ptr_dtor_nogc(free_op1)",
++    "VAR"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))",
+     "CONST"    => "",
+     "UNUSED"   => "",
+     "CV"       => "",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op2_free_op_if_var = array(
-       "ANY"      => "if (opline->op2_type == IS_VAR) {zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));}",
-       "TMP"      => "",
-       "VAR"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))",
-       "CONST"    => "",
-       "UNUSED"   => "",
-       "CV"       => "",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "if (opline->op2_type == IS_VAR) {zval_ptr_dtor_nogc(free_op2);}",
++    "ANY"      => "if (opline->op2_type == IS_VAR) {zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));}",
+     "TMP"      => "",
 -    "VAR"      => "zval_ptr_dtor_nogc(free_op2)",
++    "VAR"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))",
+     "CONST"    => "",
+     "UNUSED"   => "",
+     "CV"       => "",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op1_free_op_var_ptr = array(
-       "ANY"      => "if (opline->op1_type == IS_VAR) {zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));}",
-       "TMP"      => "",
-       "VAR"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))",
-       "CONST"    => "",
-       "UNUSED"   => "",
-       "CV"       => "",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "if (free_op1) {zval_ptr_dtor_nogc(free_op1);}",
++    "ANY"      => "if (opline->op1_type == IS_VAR) {zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));}",
+     "TMP"      => "",
 -    "VAR"      => "if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}",
++    "VAR"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))",
+     "CONST"    => "",
+     "UNUSED"   => "",
+     "CV"       => "",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op2_free_op_var_ptr = array(
-       "ANY"      => "if (opline->op2_type == IS_VAR) {zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));}",
-       "TMP"      => "",
-       "VAR"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))",
-       "CONST"    => "",
-       "UNUSED"   => "",
-       "CV"       => "",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "if (free_op2) {zval_ptr_dtor_nogc(free_op2);}",
++    "ANY"      => "if (opline->op2_type == IS_VAR) {zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));}",
+     "TMP"      => "",
 -    "VAR"      => "if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);}",
++    "VAR"      => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))",
+     "CONST"    => "",
+     "UNUSED"   => "",
+     "CV"       => "",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op1_free_unfetched = array(
@@@ -528,58 -550,58 +528,58 @@@ $op_data_type = array
  );
  
  $op_data_get_zval_ptr = array(
-       "ANY"      => "get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1)",
-       "TMP"      => "_get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC)",
-       "VAR"      => "_get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC)",
-       "CONST"    => "RT_CONSTANT((opline+1), (opline+1)->op1)",
-       "UNUSED"   => "NULL",
-       "CV"       => "_get_zval_ptr_cv_\\1((opline+1)->op1.var EXECUTE_DATA_CC)",
-       "TMPVAR"   => "_get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC)",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data)",
 -    "TMP"      => "_get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC)",
 -    "VAR"      => "_get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC)",
++    "ANY"      => "get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1)",
++    "TMP"      => "_get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC)",
+     "CONST"    => "RT_CONSTANT((opline+1), (opline+1)->op1)",
+     "UNUSED"   => "NULL",
+     "CV"       => "_get_zval_ptr_cv_\\1((opline+1)->op1.var EXECUTE_DATA_CC)",
 -    "TMPVAR"   => "_get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC)",
++    "TMPVAR"   => "_get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC)",
+     "TMPVARCV" => "???",
  );
  
  $op_data_get_zval_ptr_deref = array(
-       "ANY"      => "get_op_data_zval_ptr_deref_r((opline+1)->op1_type, (opline+1)->op1)",
-       "TMP"      => "_get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC)",
-       "VAR"      => "_get_zval_ptr_var_deref((opline+1)->op1.var EXECUTE_DATA_CC)",
-       "CONST"    => "RT_CONSTANT((opline+1), (opline+1)->op1)",
-       "UNUSED"   => "NULL",
-       "CV"       => "_get_zval_ptr_cv_deref_\\1((opline+1)->op1.var EXECUTE_DATA_CC)",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_op_data_zval_ptr_deref_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data)",
 -    "TMP"      => "_get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC)",
 -    "VAR"      => "_get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC)",
++    "ANY"      => "get_op_data_zval_ptr_deref_r((opline+1)->op1_type, (opline+1)->op1)",
++    "TMP"      => "_get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_var_deref((opline+1)->op1.var EXECUTE_DATA_CC)",
+     "CONST"    => "RT_CONSTANT((opline+1), (opline+1)->op1)",
+     "UNUSED"   => "NULL",
+     "CV"       => "_get_zval_ptr_cv_deref_\\1((opline+1)->op1.var EXECUTE_DATA_CC)",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op_data_get_zval_ptr_ptr = array(
-       "ANY"      => "get_zval_ptr_ptr((opline+1)->op1_type, (opline+1)->op1, \\1)",
-       "TMP"      => "NULL",
-       "VAR"      => "_get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC)",
-       "CONST"    => "NULL",
-       "UNUSED"   => "NULL",
-       "CV"       => "_get_zval_ptr_cv_\\1((opline+1)->op1.var EXECUTE_DATA_CC)",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "get_zval_ptr_ptr((opline+1)->op1_type, (opline+1)->op1, &free_op_data, \\1)",
++    "ANY"      => "get_zval_ptr_ptr((opline+1)->op1_type, (opline+1)->op1, \\1)",
+     "TMP"      => "NULL",
 -    "VAR"      => "_get_zval_ptr_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC)",
++    "VAR"      => "_get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC)",
+     "CONST"    => "NULL",
+     "UNUSED"   => "NULL",
+     "CV"       => "_get_zval_ptr_cv_\\1((opline+1)->op1.var EXECUTE_DATA_CC)",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op_data_free_op = array(
-       "ANY"      => "FREE_OP((opline+1)->op1_type, (opline+1)->op1.var)",
-       "TMP"      => "zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var))",
-       "VAR"      => "zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var))",
-       "CONST"    => "",
-       "UNUSED"   => "",
-       "CV"       => "",
-       "TMPVAR"   => "zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var))",
-       "TMPVARCV" => "???",
 -    "ANY"      => "FREE_OP(free_op_data)",
 -    "TMP"      => "zval_ptr_dtor_nogc(free_op_data)",
 -    "VAR"      => "zval_ptr_dtor_nogc(free_op_data)",
++    "ANY"      => "FREE_OP((opline+1)->op1_type, (opline+1)->op1.var)",
++    "TMP"      => "zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var))",
++    "VAR"      => "zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var))",
+     "CONST"    => "",
+     "UNUSED"   => "",
+     "CV"       => "",
 -    "TMPVAR"   => "zval_ptr_dtor_nogc(free_op_data)",
++    "TMPVAR"   => "zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var))",
+     "TMPVARCV" => "???",
  );
  
  $op_data_free_op_var_ptr = array(
-       "ANY"      => "if ((opline+1)->op1_type == IS_VAR) {zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));}",
-       "TMP"      => "",
-       "VAR"      => "zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));",
-       "CONST"    => "",
-       "UNUSED"   => "",
-       "CV"       => "",
-       "TMPVAR"   => "???",
-       "TMPVARCV" => "???",
 -    "ANY"      => "if (free_op_data) {zval_ptr_dtor_nogc(free_op_data);}",
++    "ANY"      => "if ((opline+1)->op1_type == IS_VAR) {zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));}",
+     "TMP"      => "",
 -    "VAR"      => "if (UNEXPECTED(free_op_data)) {zval_ptr_dtor_nogc(free_op_data);}",
++    "VAR"      => "zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));",
+     "CONST"    => "",
+     "UNUSED"   => "",
+     "CV"       => "",
+     "TMPVAR"   => "???",
+     "TMPVARCV" => "???",
  );
  
  $op_data_free_unfetched = array(
@@@ -739,233 -761,273 +739,233 @@@ function format_condition($condition) 
  
  // Generates code for opcode handler or helper
  function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name, $extra_spec=null) {
-       global $op1_type, $op2_type, $op1_get_zval_ptr, $op2_get_zval_ptr,
-               $op1_get_zval_ptr_deref, $op2_get_zval_ptr_deref,
-               $op1_get_zval_ptr_undef, $op2_get_zval_ptr_undef,
-               $op1_get_zval_ptr_ptr, $op2_get_zval_ptr_ptr,
-               $op1_get_zval_ptr_ptr_undef, $op2_get_zval_ptr_ptr_undef,
-               $op1_get_obj_zval_ptr, $op2_get_obj_zval_ptr,
-               $op1_get_obj_zval_ptr_undef, $op2_get_obj_zval_ptr_undef,
-               $op1_get_obj_zval_ptr_deref, $op2_get_obj_zval_ptr_deref,
-               $op1_get_obj_zval_ptr_ptr, $op2_get_obj_zval_ptr_ptr,
-               $op1_get_obj_zval_ptr_ptr_undef, $op2_get_obj_zval_ptr_ptr_undef,
-               $op1_free_unfetched, $op2_free_unfetched,
-               $op1_free_op, $op2_free_op, $op1_free_op_if_var, $op2_free_op_if_var,
-               $op1_free_op_var_ptr, $op2_free_op_var_ptr, $prefix,
-               $op_data_type, $op_data_get_zval_ptr,
-               $op_data_get_zval_ptr_deref, $op_data_get_zval_ptr_ptr,
-               $op_data_free_op, $op_data_free_op_var_ptr, $op_data_free_unfetched;
-       // Specializing
-       $specialized_replacements = array(
-               "/OP1_TYPE/" => $op1_type[$op1],
-               "/OP2_TYPE/" => $op2_type[$op2],
-               "/GET_OP1_ZVAL_PTR\(([^)]*)\)/" => $op1_get_zval_ptr[$op1],
-               "/GET_OP2_ZVAL_PTR\(([^)]*)\)/" => $op2_get_zval_ptr[$op2],
-               "/GET_OP1_ZVAL_PTR_DEREF\(([^)]*)\)/" => $op1_get_zval_ptr_deref[$op1],
-               "/GET_OP2_ZVAL_PTR_DEREF\(([^)]*)\)/" => $op2_get_zval_ptr_deref[$op2],
-               "/GET_OP1_ZVAL_PTR_UNDEF\(([^)]*)\)/" => $op1_get_zval_ptr_undef[$op1],
-               "/GET_OP2_ZVAL_PTR_UNDEF\(([^)]*)\)/" => $op2_get_zval_ptr_undef[$op2],
-               "/GET_OP1_ZVAL_PTR_PTR\(([^)]*)\)/" => $op1_get_zval_ptr_ptr[$op1],
-               "/GET_OP2_ZVAL_PTR_PTR\(([^)]*)\)/" => $op2_get_zval_ptr_ptr[$op2],
-               "/GET_OP1_ZVAL_PTR_PTR_UNDEF\(([^)]*)\)/" => $op1_get_zval_ptr_ptr_undef[$op1],
-               "/GET_OP2_ZVAL_PTR_PTR_UNDEF\(([^)]*)\)/" => $op2_get_zval_ptr_ptr_undef[$op2],
-               "/GET_OP1_OBJ_ZVAL_PTR\(([^)]*)\)/" => $op1_get_obj_zval_ptr[$op1],
-               "/GET_OP2_OBJ_ZVAL_PTR\(([^)]*)\)/" => $op2_get_obj_zval_ptr[$op2],
-               "/GET_OP1_OBJ_ZVAL_PTR_UNDEF\(([^)]*)\)/" => $op1_get_obj_zval_ptr_undef[$op1],
-               "/GET_OP2_OBJ_ZVAL_PTR_UNDEF\(([^)]*)\)/" => $op2_get_obj_zval_ptr_undef[$op2],
-               "/GET_OP1_OBJ_ZVAL_PTR_DEREF\(([^)]*)\)/" => $op1_get_obj_zval_ptr_deref[$op1],
-               "/GET_OP2_OBJ_ZVAL_PTR_DEREF\(([^)]*)\)/" => $op2_get_obj_zval_ptr_deref[$op2],
-               "/GET_OP1_OBJ_ZVAL_PTR_PTR\(([^)]*)\)/" => $op1_get_obj_zval_ptr_ptr[$op1],
-               "/GET_OP2_OBJ_ZVAL_PTR_PTR\(([^)]*)\)/" => $op2_get_obj_zval_ptr_ptr[$op2],
-               "/GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF\(([^)]*)\)/" => $op1_get_obj_zval_ptr_ptr_undef[$op1],
-               "/GET_OP2_OBJ_ZVAL_PTR_PTR_UNDEF\(([^)]*)\)/" => $op2_get_obj_zval_ptr_ptr_undef[$op2],
-               "/FREE_OP1\(\)/" => $op1_free_op[$op1],
-               "/FREE_OP2\(\)/" => $op2_free_op[$op2],
-               "/FREE_OP1_IF_VAR\(\)/" => $op1_free_op_if_var[$op1],
-               "/FREE_OP2_IF_VAR\(\)/" => $op2_free_op_if_var[$op2],
-               "/FREE_OP1_VAR_PTR\(\)/" => $op1_free_op_var_ptr[$op1],
-               "/FREE_OP2_VAR_PTR\(\)/" => $op2_free_op_var_ptr[$op2],
-               "/FREE_UNFETCHED_OP1\(\)/" => $op1_free_unfetched[$op1],
-               "/FREE_UNFETCHED_OP2\(\)/" => $op2_free_unfetched[$op2],
-               "/\!ZEND_VM_SPEC/m" => ($op1!="ANY"||$op2!="ANY")?"0":"1",
-               "/ZEND_VM_SPEC/m" => ($op1!="ANY"||$op2!="ANY")?"1":"0",
-               "/ZEND_VM_C_LABEL\(\s*([A-Za-z_]*)\s*\)/m" => "\\1".(($spec && $kind != ZEND_VM_KIND_CALL)?("_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec)):""),
-               "/ZEND_VM_C_GOTO\(\s*([A-Za-z_]*)\s*\)/m" => "goto \\1".(($spec && $kind != ZEND_VM_KIND_CALL)?("_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec)):""),
-               "/^#(\s*)if\s+1\s*\\|\\|.*[^\\\\]$/m" => "#\\1if 1",
-               "/^#(\s*)if\s+0\s*&&.*[^\\\\]$/m" => "#\\1if 0",
-               "/^#(\s*)elif\s+1\s*\\|\\|.*[^\\\\]$/m" => "#\\1elif 1",
-               "/^#(\s*)elif\s+0\s*&&.*[^\\\\]$/m" => "#\\1elif 0",
-               "/^#(\s*)ifdef\s+ZEND_VM_EXPORT\s*\n/m" => $export?"#\\1if 1\n":"#\\1if 0\n",
-               "/^#(\s*)ifndef\s+ZEND_VM_EXPORT\s*\n/m" => $export?"#\\1if 0\n":"#\\1if 1\n",
-               "/OP_DATA_TYPE/" => $op_data_type[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"],
-               "/GET_OP_DATA_ZVAL_PTR\(([^)]*)\)/" => $op_data_get_zval_ptr[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"],
-               "/GET_OP_DATA_ZVAL_PTR_DEREF\(([^)]*)\)/" => $op_data_get_zval_ptr_deref[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"],
-               "/GET_OP_DATA_ZVAL_PTR_PTR\(([^)]*)\)/" => $op_data_get_zval_ptr_ptr[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"],
-               "/FREE_OP_DATA\(\)/" => $op_data_free_op[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"],
-               "/FREE_OP_DATA_VAR_PTR\(\)/" => $op_data_free_op_var_ptr[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"],
-               "/FREE_UNFETCHED_OP_DATA\(\)/" => $op_data_free_unfetched[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"],
-               "/RETURN_VALUE_USED\(opline\)/" => isset($extra_spec['RETVAL']) ? $extra_spec['RETVAL'] : "RETURN_VALUE_USED(opline)",
-               "/arg_num <= MAX_ARG_FLAG_NUM/" => isset($extra_spec['QUICK_ARG']) ? $extra_spec['QUICK_ARG'] : "arg_num <= MAX_ARG_FLAG_NUM",
-               "/ZEND_VM_SMART_BRANCH\(\s*([^,)]*)\s*,\s*([^)]*)\s*\)/" => isset($extra_spec['SMART_BRANCH']) ?
-                       ($extra_spec['SMART_BRANCH'] == 1 ?
-                                       "ZEND_VM_SMART_BRANCH_JMPZ(\\1, \\2)"
-                               :       ($extra_spec['SMART_BRANCH'] == 2 ?
-                                               "ZEND_VM_SMART_BRANCH_JMPNZ(\\1, \\2)" : "ZEND_VM_SMART_BRANCH_NONE(\\1, \\2)"))
-                       :       "ZEND_VM_SMART_BRANCH(\\1, \\2)",
-               "/ZEND_VM_SMART_BRANCH_TRUE\(\s*\)/" => isset($extra_spec['SMART_BRANCH']) ?
-                       ($extra_spec['SMART_BRANCH'] == 1 ?
-                                       "ZEND_VM_SMART_BRANCH_TRUE_JMPZ()"
-                               :       ($extra_spec['SMART_BRANCH'] == 2 ?
-                                               "ZEND_VM_SMART_BRANCH_TRUE_JMPNZ()" : "ZEND_VM_SMART_BRANCH_TRUE_NONE()"))
-                       :       "ZEND_VM_SMART_BRANCH_TRUE()",
-               "/ZEND_VM_SMART_BRANCH_FALSE\(\s*\)/" => isset($extra_spec['SMART_BRANCH']) ?
-                       ($extra_spec['SMART_BRANCH'] == 1 ?
-                                       "ZEND_VM_SMART_BRANCH_FALSE_JMPZ()"
-                               :       ($extra_spec['SMART_BRANCH'] == 2 ?
-                                               "ZEND_VM_SMART_BRANCH_FALSE_JMPNZ()" : "ZEND_VM_SMART_BRANCH_FALSE_NONE()"))
-                       :       "ZEND_VM_SMART_BRANCH_FALSE()",
-               "/opline->extended_value\s*&\s*ZEND_ISEMPTY/" => isset($extra_spec['ISSET']) ?
-                       ($extra_spec['ISSET'] == 0 ? "0" : "1")
-                       : "\\0",
-               "/opline->extended_value\s*&\s*~\s*ZEND_ISEMPTY/" => isset($extra_spec['ISSET']) ?
-                       ($extra_spec['ISSET'] == 0 ? "\\0" : "opline->extended_value")
-                       : "\\0",
-       );
-       $code = preg_replace(array_keys($specialized_replacements), array_values($specialized_replacements), $code);
-       if (0 && strpos($code, '{') === 0) {
-               $code = "{\n\tfprintf(stderr, \"$name\\n\");\n" . substr($code, 1);
-       }
-       // Updating code according to selected threading model
-       switch($kind) {
-               case ZEND_VM_KIND_HYBRID:
-                       $code = preg_replace_callback(
-                               array(
-                                       "/EXECUTE_DATA(?=[^_])/m",
-                                       "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
-                                       "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
-                               ),
-                               function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec) {
-                                       if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
-                                               return "execute_data";
-                                       } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
-                                               global $opcodes, $opnames;
-                                               $name = $matches[1];
-                                               $opcode = $opcodes[$opnames[$name]];
-                                               return "goto " . opcode_name($name, $spec, $op1, $op2, $extra_spec) . "_LABEL";
-                                       } else {
-                                               // ZEND_VM_DISPATCH_TO_HELPER
-                                               if (is_hot_helper($matches[1])) {
-                                                       if (isset($matches[2])) {
-                                                               // extra args
-                                                               $args = preg_replace("/,\s*([A-Za-z0-9_]*)\s*,\s*([^,)\s]*)\s*/", "$1 = $2; ", $matches[2]);
-                                                               return $args . "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "_LABEL";
-                                                       }
-                                                       return "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "_LABEL";
-                                               }
-                                               if (isset($matches[2])) {
-                                                       // extra args
-                                                       $args = substr(preg_replace("/,\s*[A-Za-z0-9_]*\s*,\s*([^,)\s]*)\s*/", ", $1", $matches[2]), 2);
-                                                       return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "(" . $args. " ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC))";
-                                               }
-                                               return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
-                                       }
-                               },
-                               $code);
-                       break;
-               case ZEND_VM_KIND_CALL:
-                       $code = preg_replace_callback(
-                               array(
-                                       "/EXECUTE_DATA(?=[^_])/m",
-                                       "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
-                                       "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
-                               ),
-                               function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec, $name) {
-                                       if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
-                                               return "execute_data";
-                                       } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
-                                               global $opcodes, $opnames;
-                                               $handler = $matches[1];
-                                               $opcode = $opcodes[$opnames[$handler]];
-                                               $inline =
-                                                       ZEND_VM_KIND == ZEND_VM_KIND_HYBRID &&
-                                                   isset($opcode["use"]) &&
-                                                       is_hot_handler($opcode["hot"], $op1, $op2, $extra_spec) &&
-                                                       is_hot_handler($opcodes[$opnames[$name]]["hot"], $op1, $op2, $extra_spec) ?
-                                                       "_INLINE" : "";
-                                               return "ZEND_VM_TAIL_CALL(" . opcode_name($handler, $spec, $op1, $op2, $extra_spec) . $inline . "_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
-                                       } else {
-                                               // ZEND_VM_DISPATCH_TO_HELPER
-                                               if (isset($matches[2])) {
-                                                       // extra args
-                                                       $args = substr(preg_replace("/,\s*[A-Za-z0-9_]*\s*,\s*([^,)\s]*)\s*/", ", $1", $matches[2]), 2);
-                                                       return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "(" . $args. " ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC))";
-                                               }
-                                               return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
-                                       }
-                               },
-                               $code);
-                       break;
-               case ZEND_VM_KIND_SWITCH:
-                       $code = preg_replace_callback(
-                               array(
-                                       "/EXECUTE_DATA(?=[^_])/m",
-                                       "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
-                                       "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
-                               ),
-                               function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec) {
-                                       if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
-                                               return "execute_data";
-                                       } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
-                                               return "goto " . opcode_name($matches[1], $spec, $op1, $op2, $extra_spec) . "_LABEL";
-                                       } else {
-                                               // ZEND_VM_DISPATCH_TO_HELPER
-                                               if (isset($matches[2])) {
-                                                       // extra args
-                                                       $args = preg_replace("/,\s*([A-Za-z0-9_]*)\s*,\s*([^,)\s]*)\s*/", "$1 = $2; ", $matches[2]);
-                                                       return $args .  "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec);
-                                               }
-                                               return "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec);
-                                       }
-                               },
-                                       $code);
-                       break;
-               case ZEND_VM_KIND_GOTO:
-                       $code = preg_replace_callback(
-                               array(
-                                       "/EXECUTE_DATA(?=[^_])/m",
-                                       "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
-                                       "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
-                               ),
-                               function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec) {
-                                       if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
-                                               return "execute_data";
-                                       } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
-                                               return "goto " . opcode_name($matches[1], $spec, $op1, $op2, $extra_spec) . "_LABEL";
-                                       } else {
-                                               // ZEND_VM_DISPATCH_TO_HELPER
-                                               if (isset($matches[2])) {
-                                                       // extra args
-                                                       $args = preg_replace("/,\s*([A-Za-z0-9_]*)\s*,\s*([^,)\s]*)\s*/", "$1 = $2; ", $matches[2]);
-                                                       return $args .  "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec);
-                                               }
-                                               return "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec);
-                                       }
-                               },
-                                       $code);
-                       break;
-       }
-       /* Remove unnecessary ';' */
-       $code = preg_replace('/^\s*;\s*$/m', '', $code);
-       /* Remove WS */
-       $code = preg_replace('/[ \t]+\n/m', "\n", $code);
-       out($f, $code);
+     global $op1_type, $op2_type, $op1_get_zval_ptr, $op2_get_zval_ptr,
+         $op1_get_zval_ptr_deref, $op2_get_zval_ptr_deref,
+         $op1_get_zval_ptr_undef, $op2_get_zval_ptr_undef,
+         $op1_get_zval_ptr_ptr, $op2_get_zval_ptr_ptr,
+         $op1_get_zval_ptr_ptr_undef, $op2_get_zval_ptr_ptr_undef,
+         $op1_get_obj_zval_ptr, $op2_get_obj_zval_ptr,
+         $op1_get_obj_zval_ptr_undef, $op2_get_obj_zval_ptr_undef,
+         $op1_get_obj_zval_ptr_deref, $op2_get_obj_zval_ptr_deref,
+         $op1_get_obj_zval_ptr_ptr, $op2_get_obj_zval_ptr_ptr,
+         $op1_get_obj_zval_ptr_ptr_undef, $op2_get_obj_zval_ptr_ptr_undef,
 -        $op1_free, $op2_free, $op1_free_unfetched, $op2_free_unfetched,
++        $op1_free_unfetched, $op2_free_unfetched,
+         $op1_free_op, $op2_free_op, $op1_free_op_if_var, $op2_free_op_if_var,
+         $op1_free_op_var_ptr, $op2_free_op_var_ptr, $prefix,
+         $op_data_type, $op_data_get_zval_ptr,
+         $op_data_get_zval_ptr_deref, $op_data_get_zval_ptr_ptr,
+         $op_data_free_op, $op_data_free_op_var_ptr, $op_data_free_unfetched;
+     // Specializing
+     $specialized_replacements = array(
+         "/OP1_TYPE/" => $op1_type[$op1],
+         "/OP2_TYPE/" => $op2_type[$op2],
 -        "/OP1_FREE/" => $op1_free[$op1],
 -        "/OP2_FREE/" => $op2_free[$op2],
+         "/GET_OP1_ZVAL_PTR\(([^)]*)\)/" => $op1_get_zval_ptr[$op1],
+         "/GET_OP2_ZVAL_PTR\(([^)]*)\)/" => $op2_get_zval_ptr[$op2],
+         "/GET_OP1_ZVAL_PTR_DEREF\(([^)]*)\)/" => $op1_get_zval_ptr_deref[$op1],
+         "/GET_OP2_ZVAL_PTR_DEREF\(([^)]*)\)/" => $op2_get_zval_ptr_deref[$op2],
+         "/GET_OP1_ZVAL_PTR_UNDEF\(([^)]*)\)/" => $op1_get_zval_ptr_undef[$op1],
+         "/GET_OP2_ZVAL_PTR_UNDEF\(([^)]*)\)/" => $op2_get_zval_ptr_undef[$op2],
+         "/GET_OP1_ZVAL_PTR_PTR\(([^)]*)\)/" => $op1_get_zval_ptr_ptr[$op1],
+         "/GET_OP2_ZVAL_PTR_PTR\(([^)]*)\)/" => $op2_get_zval_ptr_ptr[$op2],
+         "/GET_OP1_ZVAL_PTR_PTR_UNDEF\(([^)]*)\)/" => $op1_get_zval_ptr_ptr_undef[$op1],
+         "/GET_OP2_ZVAL_PTR_PTR_UNDEF\(([^)]*)\)/" => $op2_get_zval_ptr_ptr_undef[$op2],
+         "/GET_OP1_OBJ_ZVAL_PTR\(([^)]*)\)/" => $op1_get_obj_zval_ptr[$op1],
+         "/GET_OP2_OBJ_ZVAL_PTR\(([^)]*)\)/" => $op2_get_obj_zval_ptr[$op2],
+         "/GET_OP1_OBJ_ZVAL_PTR_UNDEF\(([^)]*)\)/" => $op1_get_obj_zval_ptr_undef[$op1],
+         "/GET_OP2_OBJ_ZVAL_PTR_UNDEF\(([^)]*)\)/" => $op2_get_obj_zval_ptr_undef[$op2],
+         "/GET_OP1_OBJ_ZVAL_PTR_DEREF\(([^)]*)\)/" => $op1_get_obj_zval_ptr_deref[$op1],
+         "/GET_OP2_OBJ_ZVAL_PTR_DEREF\(([^)]*)\)/" => $op2_get_obj_zval_ptr_deref[$op2],
+         "/GET_OP1_OBJ_ZVAL_PTR_PTR\(([^)]*)\)/" => $op1_get_obj_zval_ptr_ptr[$op1],
+         "/GET_OP2_OBJ_ZVAL_PTR_PTR\(([^)]*)\)/" => $op2_get_obj_zval_ptr_ptr[$op2],
+         "/GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF\(([^)]*)\)/" => $op1_get_obj_zval_ptr_ptr_undef[$op1],
+         "/GET_OP2_OBJ_ZVAL_PTR_PTR_UNDEF\(([^)]*)\)/" => $op2_get_obj_zval_ptr_ptr_undef[$op2],
+         "/FREE_OP1\(\)/" => $op1_free_op[$op1],
+         "/FREE_OP2\(\)/" => $op2_free_op[$op2],
+         "/FREE_OP1_IF_VAR\(\)/" => $op1_free_op_if_var[$op1],
+         "/FREE_OP2_IF_VAR\(\)/" => $op2_free_op_if_var[$op2],
+         "/FREE_OP1_VAR_PTR\(\)/" => $op1_free_op_var_ptr[$op1],
+         "/FREE_OP2_VAR_PTR\(\)/" => $op2_free_op_var_ptr[$op2],
+         "/FREE_UNFETCHED_OP1\(\)/" => $op1_free_unfetched[$op1],
+         "/FREE_UNFETCHED_OP2\(\)/" => $op2_free_unfetched[$op2],
+         "/\!ZEND_VM_SPEC/m" => ($op1!="ANY"||$op2!="ANY")?"0":"1",
+         "/ZEND_VM_SPEC/m" => ($op1!="ANY"||$op2!="ANY")?"1":"0",
+         "/ZEND_VM_C_LABEL\(\s*([A-Za-z_]*)\s*\)/m" => "\\1".(($spec && $kind != ZEND_VM_KIND_CALL)?("_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec)):""),
+         "/ZEND_VM_C_GOTO\(\s*([A-Za-z_]*)\s*\)/m" => "goto \\1".(($spec && $kind != ZEND_VM_KIND_CALL)?("_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec)):""),
+         "/^#(\s*)if\s+1\s*\\|\\|.*[^\\\\]$/m" => "#\\1if 1",
+         "/^#(\s*)if\s+0\s*&&.*[^\\\\]$/m" => "#\\1if 0",
+         "/^#(\s*)elif\s+1\s*\\|\\|.*[^\\\\]$/m" => "#\\1elif 1",
+         "/^#(\s*)elif\s+0\s*&&.*[^\\\\]$/m" => "#\\1elif 0",
+         "/^#(\s*)ifdef\s+ZEND_VM_EXPORT\s*\n/m" => $export?"#\\1if 1\n":"#\\1if 0\n",
+         "/^#(\s*)ifndef\s+ZEND_VM_EXPORT\s*\n/m" => $export?"#\\1if 0\n":"#\\1if 1\n",
+         "/OP_DATA_TYPE/" => $op_data_type[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"],
+         "/GET_OP_DATA_ZVAL_PTR\(([^)]*)\)/" => $op_data_get_zval_ptr[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"],
+         "/GET_OP_DATA_ZVAL_PTR_DEREF\(([^)]*)\)/" => $op_data_get_zval_ptr_deref[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"],
+         "/GET_OP_DATA_ZVAL_PTR_PTR\(([^)]*)\)/" => $op_data_get_zval_ptr_ptr[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"],
+         "/FREE_OP_DATA\(\)/" => $op_data_free_op[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"],
+         "/FREE_OP_DATA_VAR_PTR\(\)/" => $op_data_free_op_var_ptr[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"],
+         "/FREE_UNFETCHED_OP_DATA\(\)/" => $op_data_free_unfetched[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"],
+         "/RETURN_VALUE_USED\(opline\)/" => isset($extra_spec['RETVAL']) ? $extra_spec['RETVAL'] : "RETURN_VALUE_USED(opline)",
+         "/arg_num <= MAX_ARG_FLAG_NUM/" => isset($extra_spec['QUICK_ARG']) ? $extra_spec['QUICK_ARG'] : "arg_num <= MAX_ARG_FLAG_NUM",
+         "/ZEND_VM_SMART_BRANCH\(\s*([^,)]*)\s*,\s*([^)]*)\s*\)/" => isset($extra_spec['SMART_BRANCH']) ?
+             ($extra_spec['SMART_BRANCH'] == 1 ?
+                     "ZEND_VM_SMART_BRANCH_JMPZ(\\1, \\2)"
+                 :     ($extra_spec['SMART_BRANCH'] == 2 ?
 -                        "ZEND_VM_SMART_BRANCH_JMPNZ(\\1, \\2)" : ""))
++                        "ZEND_VM_SMART_BRANCH_JMPNZ(\\1, \\2)" : "ZEND_VM_SMART_BRANCH_NONE(\\1, \\2)"))
+             : "ZEND_VM_SMART_BRANCH(\\1, \\2)",
+         "/ZEND_VM_SMART_BRANCH_TRUE\(\s*\)/" => isset($extra_spec['SMART_BRANCH']) ?
+             ($extra_spec['SMART_BRANCH'] == 1 ?
+                     "ZEND_VM_SMART_BRANCH_TRUE_JMPZ()"
+                 :     ($extra_spec['SMART_BRANCH'] == 2 ?
 -                        "ZEND_VM_SMART_BRANCH_TRUE_JMPNZ()" : ""))
++                        "ZEND_VM_SMART_BRANCH_TRUE_JMPNZ()" : "ZEND_VM_SMART_BRANCH_TRUE_NONE()"))
+             : "ZEND_VM_SMART_BRANCH_TRUE()",
+         "/ZEND_VM_SMART_BRANCH_FALSE\(\s*\)/" => isset($extra_spec['SMART_BRANCH']) ?
+             ($extra_spec['SMART_BRANCH'] == 1 ?
+                     "ZEND_VM_SMART_BRANCH_FALSE_JMPZ()"
+                 :     ($extra_spec['SMART_BRANCH'] == 2 ?
 -                        "ZEND_VM_SMART_BRANCH_FALSE_JMPNZ()" : ""))
++                        "ZEND_VM_SMART_BRANCH_FALSE_JMPNZ()" : "ZEND_VM_SMART_BRANCH_FALSE_NONE()"))
+             : "ZEND_VM_SMART_BRANCH_FALSE()",
+         "/opline->extended_value\s*&\s*ZEND_ISEMPTY/" => isset($extra_spec['ISSET']) ?
+             ($extra_spec['ISSET'] == 0 ? "0" : "1")
+             : "\\0",
+         "/opline->extended_value\s*&\s*~\s*ZEND_ISEMPTY/" => isset($extra_spec['ISSET']) ?
+             ($extra_spec['ISSET'] == 0 ? "\\0" : "opline->extended_value")
+             : "\\0",
+     );
+     $code = preg_replace(array_keys($specialized_replacements), array_values($specialized_replacements), $code);
+     if (0 && strpos($code, '{') === 0) {
+         $code = "{\n\tfprintf(stderr, \"$name\\n\");\n" . substr($code, 1);
+     }
+     // Updating code according to selected threading model
+     switch($kind) {
+         case ZEND_VM_KIND_HYBRID:
+             $code = preg_replace_callback(
+                 array(
+                     "/EXECUTE_DATA(?=[^_])/m",
+                     "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
+                     "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
+                 ),
+                 function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec) {
+                     if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
+                         return "execute_data";
+                     } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
+                         global $opcodes, $opnames;
+                         $name = $matches[1];
+                         $opcode = $opcodes[$opnames[$name]];
+                         return "goto " . opcode_name($name, $spec, $op1, $op2, $extra_spec) . "_LABEL";
+                     } else {
+                         // ZEND_VM_DISPATCH_TO_HELPER
+                         if (is_hot_helper($matches[1])) {
+                             if (isset($matches[2])) {
+                                 // extra args
+                                 $args = preg_replace("/,\s*([A-Za-z0-9_]*)\s*,\s*([^,)\s]*)\s*/", "$1 = $2; ", $matches[2]);
+                                 return $args . "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "_LABEL";
+                             }
+                             return "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "_LABEL";
+                         }
+                         if (isset($matches[2])) {
+                             // extra args
+                             $args = substr(preg_replace("/,\s*[A-Za-z0-9_]*\s*,\s*([^,)\s]*)\s*/", ", $1", $matches[2]), 2);
+                             return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "(" . $args. " ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC))";
+                         }
+                         return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
+                     }
+                 },
+                 $code);
+             break;
+         case ZEND_VM_KIND_CALL:
+             $code = preg_replace_callback(
+                 array(
+                     "/EXECUTE_DATA(?=[^_])/m",
+                     "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
+                     "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
+                 ),
+                 function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec, $name) {
+                     if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
+                         return "execute_data";
+                     } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
+                         global $opcodes, $opnames;
+                         $handler = $matches[1];
+                         $opcode = $opcodes[$opnames[$handler]];
+                         $inline =
+                             ZEND_VM_KIND == ZEND_VM_KIND_HYBRID &&
+                             isset($opcode["use"]) &&
+                             is_hot_handler($opcode["hot"], $op1, $op2, $extra_spec) &&
+                             is_hot_handler($opcodes[$opnames[$name]]["hot"], $op1, $op2, $extra_spec) ?
+                             "_INLINE" : "";
+                         return "ZEND_VM_TAIL_CALL(" . opcode_name($handler, $spec, $op1, $op2, $extra_spec) . $inline . "_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
+                     } else {
+                         // ZEND_VM_DISPATCH_TO_HELPER
+                         if (isset($matches[2])) {
+                             // extra args
+                             $args = substr(preg_replace("/,\s*[A-Za-z0-9_]*\s*,\s*([^,)\s]*)\s*/", ", $1", $matches[2]), 2);
+                             return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "(" . $args. " ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC))";
+                         }
+                         return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2, $extra_spec) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
+                     }
+                 },
+                 $code);
+             break;
+         case ZEND_VM_KIND_SWITCH:
+             $code = preg_replace_callback(
+                 array(
+                     "/EXECUTE_DATA(?=[^_])/m",
+                     "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
+                     "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
+                 ),
+                 function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec) {
+                     if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
+                         return "execute_data";
+                     } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
+                         return "goto " . opcode_name($matches[1], $spec, $op1, $op2, $extra_spec) . "_LABEL";
+                     } else {
+                         // ZEND_VM_DISPATCH_TO_HELPER
+                         if (isset($matches[2])) {
+                             // extra args
+                             $args = preg_replace("/,\s*([A-Za-z0-9_]*)\s*,\s*([^,)\s]*)\s*/", "$1 = $2; ", $matches[2]);
+                             return $args .  "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec);
+                         }
+                         return "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec);
+                     }
+                 },
+                     $code);
+             break;
+         case ZEND_VM_KIND_GOTO:
+             $code = preg_replace_callback(
+                 array(
+                     "/EXECUTE_DATA(?=[^_])/m",
+                     "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
+                     "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
+                 ),
+                 function($matches) use ($spec, $prefix, $op1, $op2, $extra_spec) {
+                     if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
+                         return "execute_data";
+                     } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
+                         return "goto " . opcode_name($matches[1], $spec, $op1, $op2, $extra_spec) . "_LABEL";
+                     } else {
+                         // ZEND_VM_DISPATCH_TO_HELPER
+                         if (isset($matches[2])) {
+                             // extra args
+                             $args = preg_replace("/,\s*([A-Za-z0-9_]*)\s*,\s*([^,)\s]*)\s*/", "$1 = $2; ", $matches[2]);
+                             return $args .  "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec);
+                         }
+                         return "goto " . helper_name($matches[1], $spec, $op1, $op2, $extra_spec);
+                     }
+                 },
+                     $code);
+             break;
+     }
 -    /* Remove unused free_op1 and free_op2 declarations */
 -    if ($spec && preg_match_all('/^\s*zend_free_op\s+[^;]+;\s*$/m', $code, $matches, PREG_SET_ORDER)) {
 -        $n = 0;
 -        foreach ($matches as $match) {
 -          $code = preg_replace('/'.preg_quote($match[0],'/').'/', "\$D$n", $code);
 -          ++$n;
 -        }
 -        $del_free_op1 = (strpos($code, "free_op1") === false);
 -        $del_free_op2 = (strpos($code, "free_op2") === false);
 -        $del_free_op_data = (strpos($code, "free_op_data") === false);
 -        $n = 0;
 -        foreach ($matches as $match) {
 -            $dcl = $match[0];
 -            $changed = 0;
 -            if ($del_free_op1 && strpos($dcl, "free_op1") !== false) {
 -                $dcl = preg_replace("/free_op1\s*,\s*/", "", $dcl);
 -                $dcl = preg_replace("/free_op1\s*;/", ";", $dcl);
 -                $changed = 1;
 -            }
 -            if ($del_free_op2 && strpos($dcl, "free_op2") !== false) {
 -                $dcl = preg_replace("/free_op2\s*,\s*/", "", $dcl);
 -                $dcl = preg_replace("/free_op2\s*;/", ";", $dcl);
 -                $changed = 1;
 -            }
 -            if ($del_free_op_data && strpos($dcl, "free_op_data") !== false) {
 -                $dcl = preg_replace("/free_op_data\s*,\s*/", "", $dcl);
 -                $dcl = preg_replace("/free_op_data\s*;/", ";", $dcl);
 -                $changed = 1;
 -            }
 -            if ($changed) {
 -                $dcl = preg_replace("/,\s*;/", ";", $dcl);
 -                $dcl = preg_replace("/zend_free_op\s*;/", "", $dcl);
 -            }
 -          $code = preg_replace("/\\\$D$n/", $dcl, $code);
 -          ++$n;
 -        }
 -    }
 -
+     /* Remove unnecessary ';' */
+     $code = preg_replace('/^\s*;\s*$/m', '', $code);
+     /* Remove WS */
+     $code = preg_replace('/[ \t]+\n/m', "\n", $code);
+     out($f, $code);
  }
  
  function skip_extra_spec_function($op1, $op2, $extra_spec) {
@@@ -2301,726 -2363,778 +2301,726 @@@ function parse_spec_rules($def, $lineno
  }
  
  function gen_vm($def, $skel) {
-       global $definition_file, $skeleton_file, $executor_file,
-               $op_types, $list, $opcodes, $helpers, $params, $opnames,
-               $vm_op_flags, $used_extra_spec;
-       // Load definition file
-       $in = @file($def);
-       if (!$in) {
-               die("ERROR: Can not open definition file '$def'\n");
-       }
-       // We need absolute path to definition file to use it in #line directives
-       $definition_file = realpath($def);
-       // Load skeleton file
-       $skl = @file($skel);
-       if (!$skl) {
-               die("ERROR: Can not open skeleton file '$skel'\n");
-       }
-       // We need absolute path to skeleton file to use it in #line directives
-       $skeleton_file = realpath($skel);
-       // Parse definition file into tree
-       $lineno         = 0;
-       $handler        = null;
-       $helper         = null;
-       $max_opcode_len = 0;
-       $max_opcode     = 0;
-       $extra_num      = 256;
-       $export         = array();
-       foreach ($in as $line) {
-               ++$lineno;
-               if (strpos($line,"ZEND_VM_HANDLER(") === 0 ||
-                   strpos($line,"ZEND_VM_INLINE_HANDLER(") === 0 ||
-                   strpos($line,"ZEND_VM_HOT_HANDLER(") === 0 ||
-                   strpos($line,"ZEND_VM_HOT_NOCONST_HANDLER(") === 0 ||
-                   strpos($line,"ZEND_VM_HOT_NOCONSTCONST_HANDLER(") === 0 ||
-                   strpos($line,"ZEND_VM_HOT_SEND_HANDLER(") === 0 ||
-                   strpos($line,"ZEND_VM_HOT_OBJ_HANDLER(") === 0 ||
-                   strpos($line,"ZEND_VM_COLD_HANDLER(") === 0 ||
-                   strpos($line,"ZEND_VM_COLD_CONST_HANDLER(") === 0 ||
-                   strpos($line,"ZEND_VM_COLD_CONSTCONST_HANDLER(") === 0) {
-                 // Parsing opcode handler's definition
-                       if (preg_match(
-                                       "/^ZEND_VM_(HOT_|INLINE_|HOT_OBJ_|HOT_SEND_|HOT_NOCONST_|HOT_NOCONSTCONST_|COLD_|COLD_CONST_|COLD_CONSTCONST_)?HANDLER\(\s*([0-9]+)\s*,\s*([A-Z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/",
-                                       $line,
-                                       $m) == 0) {
-                               die("ERROR ($def:$lineno): Invalid ZEND_VM_HANDLER definition.\n");
-                       }
-                       $hot = !empty($m[1]) ? $m[1] : false;
-                       $code = (int)$m[2];
-                       $op   = $m[3];
-                       $len  = strlen($op);
-                       $op1  = parse_operand_spec($def, $lineno, $m[4], $flags1);
-                       $op2  = parse_operand_spec($def, $lineno, $m[5], $flags2);
-                       $flags = $flags1 | ($flags2 << 8);
-                       if (!empty($m[7])) {
-                               $flags |= parse_ext_spec($def, $lineno, $m[7]);
-                       }
-                       if ($len > $max_opcode_len) {
-                               $max_opcode_len = $len;
-                       }
-                       if ($code > $max_opcode) {
-                               $max_opcode = $code;
-                       }
-                       if (isset($opcodes[$code])) {
-                               die("ERROR ($def:$lineno): Opcode with code '$code' is already defined.\n");
-                       }
-                       if (isset($opnames[$op])) {
-                               die("ERROR ($def:$lineno): Opcode with name '$op' is already defined.\n");
-                       }
-                       $opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>"","flags"=>$flags,"hot"=>$hot);
-                       if (isset($m[9])) {
-                               $opcodes[$code]["spec"] = parse_spec_rules($def, $lineno, $m[9]);
-                               if (isset($opcodes[$code]["spec"]["NO_CONST_CONST"])) {
-                                       $opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_NO_CONST_CONST"];
-                               }
-                               if (isset($opcodes[$code]["spec"]["COMMUTATIVE"])) {
-                                       $opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_COMMUTATIVE"];
-                               }
-                       }
-                       $opnames[$op] = $code;
-                       $handler = $code;
-                       $helper = null;
-                       $list[$lineno] = array("handler"=>$handler);
-               } else if (strpos($line,"ZEND_VM_TYPE_SPEC_HANDLER(") === 0 ||
-                          strpos($line,"ZEND_VM_INLINE_TYPE_SPEC_HANDLER(") === 0 ||
-                          strpos($line,"ZEND_VM_HOT_TYPE_SPEC_HANDLER(") === 0 ||
-                          strpos($line,"ZEND_VM_HOT_NOCONST_TYPE_SPEC_HANDLER(") === 0 ||
-                          strpos($line,"ZEND_VM_HOT_NOCONSTCONST_TYPE_SPEC_HANDLER(") === 0 ||
-                          strpos($line,"ZEND_VM_HOT_SEND_TYPE_SPEC_HANDLER(") === 0 ||
-                          strpos($line,"ZEND_VM_HOT_OBJ_TYPE_SPEC_HANDLER(") === 0) {
-                 // Parsing opcode handler's definition
-                       if (preg_match(
-                                       "/^ZEND_VM_(HOT_|INLINE_|HOT_OBJ_|HOT_SEND_|HOT_NOCONST_|HOT_NOCONSTCONST_)?TYPE_SPEC_HANDLER\(\s*([A-Z_|]+)\s*,\s*((?:[^(,]|\([^()]*|(?R)*\))*),\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/",
-                                       $line,
-                                       $m) == 0) {
-                               die("ERROR ($def:$lineno): Invalid ZEND_VM_TYPE_HANDLER_HANDLER definition.\n");
-                       }
-                       $hot = !empty($m[1]) ? $m[1] : false;
-                       $orig_op_list = $m[2];
-                       $code = $extra_num++;
-                       foreach (explode('|', $orig_op_list) as $orig_op) {
-                               if (!isset($opnames[$orig_op])) {
-                                       die("ERROR ($def:$lineno): Opcode with name '$orig_op' is not defined.\n");
-                               }
-                               $orig_code = $opnames[$orig_op];
-                               $condition = $m[3];
-                               $opcodes[$orig_code]['type_spec'][$code] = $condition;
-                       }
-                       $op = $m[4];
-                       $op1  = parse_operand_spec($def, $lineno, $m[5], $flags1);
-                       $op2  = parse_operand_spec($def, $lineno, $m[6], $flags2);
-                       $flags = $flags1 | ($flags2 << 8);
-                       if (!empty($m[8])) {
-                               $flags |= parse_ext_spec($def, $lineno, $m[8]);
-                       }
-                       if (isset($opcodes[$code])) {
-                               die("ERROR ($def:$lineno): Opcode with name '$code' is already defined.\n");
-                       }
-                       $used_extra_spec["TYPE"] = 1;
-                       $opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>"","flags"=>$flags,"hot"=>$hot,"is_type_spec"=>true);
-                       if (isset($m[10])) {
-                               $opcodes[$code]["spec"] = parse_spec_rules($def, $lineno, $m[10]);
-                               if (isset($opcodes[$code]["spec"]["NO_CONST_CONST"])) {
-                                       $opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_NO_CONST_CONST"];
-                               }
-                               if (isset($opcodes[$code]["spec"]["COMMUTATIVE"])) {
-                                       $opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_COMMUTATIVE"];
-                               }
-                       }
-                       $opnames[$op] = $code;
-                       $handler = $code;
-                       $helper = null;
-                       $list[$lineno] = array("handler"=>$handler);
-               } else if (strpos($line,"ZEND_VM_HELPER(") === 0 ||
-                          strpos($line,"ZEND_VM_INLINE_HELPER(") === 0 ||
-                          strpos($line,"ZEND_VM_COLD_HELPER(") === 0 ||
-                          strpos($line,"ZEND_VM_HOT_HELPER(") === 0) {
-                 // Parsing helper's definition
-                       if (preg_match(
-                                       "/^ZEND_VM(_INLINE|_COLD|_HOT)?_HELPER\(\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(?:,\s*SPEC\(([A-Z_|=,]+)\)\s*)?(?:,\s*([^)]*)\s*)?\)/",
-                                       $line,
-                                       $m) == 0) {
-                               die("ERROR ($def:$lineno): Invalid ZEND_VM_HELPER definition.\n");
-                       }
-                       $inline = !empty($m[1]) && $m[1] === "_INLINE";
-                       $cold   = !empty($m[1]) && $m[1] === "_COLD";
-                       $hot    = !empty($m[1]) && $m[1] === "_HOT";
-                       $helper = $m[2];
-                       $op1    = parse_operand_spec($def, $lineno, $m[3], $flags1);
-                       $op2    = parse_operand_spec($def, $lineno, $m[4], $flags2);
-                       $param  = isset($m[6]) ? $m[6] : null;
-                       if (isset($helpers[$helper])) {
-                               die("ERROR ($def:$lineno): Helper with name '$helper' is already defined.\n");
-                       }
-                       // Store parameters
-                       if (ZEND_VM_KIND == ZEND_VM_KIND_GOTO
-                        || ZEND_VM_KIND == ZEND_VM_KIND_SWITCH
-                        || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID && $hot)) {
-                               foreach (explode(",", $param) as $p) {
-                                       $p = trim($p);
-                                       if ($p !== "") {
-                                               $params[$p] = 1;
-                                       }
-                               }
-                       }
-                       $helpers[$helper] = array("op1"=>$op1,"op2"=>$op2,"param"=>$param,"code"=>"","inline"=>$inline,"cold"=>$cold,"hot"=>$hot);
-                       if (!empty($m[5])) {
-                               $helpers[$helper]["spec"] = parse_spec_rules($def, $lineno, $m[5]);
-                       }
-                       $handler = null;
-                       $list[$lineno] = array("helper"=>$helper);
-               } else if (strpos($line,"ZEND_VM_EXPORT_HANDLER(") === 0) {
-                       if (preg_match(
-                                       "/^ZEND_VM_EXPORT_HANDLER\(\s*([A-Za-z_]+)\s*,\s*([A-Z_]+)\s*\)/",
-                                       $line,
-                                       $m) == 0) {
-                               die("ERROR ($def:$lineno): Invalid ZEND_VM_EXPORT_HANDLER definition.\n");
-                       }
-                       if (!isset($opnames[$m[2]])) {
-                               die("ERROR ($def:$lineno): opcode '{$m[2]}' is not defined.\n");
-                       }
-                       $export[] = array("handler",$m[1],$m[2]);
-               } else if (strpos($line,"ZEND_VM_EXPORT_HELPER(") === 0) {
-                       if (preg_match(
-                                       "/^ZEND_VM_EXPORT_HELPER\(\s*([A-Za-z_]+)\s*,\s*([A-Za-z_]+)\s*\)/",
-                                       $line,
-                                       $m) == 0) {
-                               die("ERROR ($def:$lineno): Invalid ZEND_VM_EXPORT_HELPER definition.\n");
-                       }
-                       if (!isset($helpers[$m[2]])) {
-                               die("ERROR ($def:$lineno): helper '{$m[2]}' is not defined.\n");
-                       }
-                       $export[] = array("helper",$m[1],$m[2]);
-               } else if (strpos($line,"ZEND_VM_DEFINE_OP(") === 0) {
-                       if (preg_match(
-                                       "/^ZEND_VM_DEFINE_OP\(\s*([0-9]+)\s*,\s*([A-Z_]+)\s*\);/",
-                                       $line,
-                                       $m) == 0) {
-                               die("ERROR ($def:$lineno): Invalid ZEND_VM_DEFINE_OP definition.\n");
-                       }
-                       $code = (int)$m[1];
-                       $op   = $m[2];
-                       $len  = strlen($op);
-                       if ($len > $max_opcode_len) {
-                               $max_opcode_len = $len;
-                       }
-                       if ($code > $max_opcode) {
-                               $max_opcode = $code;
-                       }
-                       if (isset($opcodes[$code])) {
-                               die("ERROR ($def:$lineno): Opcode with code '$code' is already defined.\n");
-                       }
-                       if (isset($opnames[$op])) {
-                               die("ERROR ($def:$lineno): Opcode with name '$op' is already defined.\n");
-                       }
-                       $opcodes[$code] = array("op"=>$op,"code"=>"");
-                       $opnames[$op] = $code;
-               } else if ($handler !== null) {
-                 // Add line of code to current opcode handler
-                       $opcodes[$handler]["code"] .= $line;
-               } else if ($helper !== null) {
-                 // Add line of code to current helper
-                       $helpers[$helper]["code"] .= $line;
-               }
-       }
-       ksort($opcodes);
-       // Search for opcode handlers those are used by other opcode handlers
-       foreach ($opcodes as $dsc) {
-               if (preg_match("/^\s*{\s*ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)\s*;\s*}\s*/", $dsc["code"], $m)) {
-                       $op = $m[1];
-                       if (!isset($opnames[$op])) {
-                               die("ERROR ($def:$lineno): Opcode with name '$op' is not defined.\n");
-                       }
-                       $opcodes[$opnames[$dsc['op']]]['alias'] = $op;
-                       if (!ZEND_VM_SPEC && ZEND_VM_KIND == ZEND_VM_KIND_SWITCH) {
-                               $code = $opnames[$op];
-                               $opcodes[$code]['use'] = 1;
-                       }
-               } else if (preg_match_all("/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m", $dsc["code"], $mm, PREG_SET_ORDER)) {
-                       foreach ($mm as $m) {
-                               $op = $m[1];
-                               if (!isset($opnames[$op])) {
-                                       die("ERROR ($def:$lineno): Opcode with name '$op' is not defined.\n");
-                               }
-                               $code = $opnames[$op];
-                               $opcodes[$code]['use'] = 1;
-                       }
-               }
-       }
-       // Generate opcode #defines (zend_vm_opcodes.h)
-       $code_len = strlen((string)$max_opcode);
-       $f = fopen(__DIR__ . "/zend_vm_opcodes.h", "w+") or die("ERROR: Cannot create zend_vm_opcodes.h\n");
-       // Insert header
-       out($f, HEADER_TEXT);
-       fputs($f, "#ifndef ZEND_VM_OPCODES_H\n#define ZEND_VM_OPCODES_H\n\n");
-       fputs($f, "#define ZEND_VM_SPEC\t\t" . ZEND_VM_SPEC . "\n");
-       fputs($f, "#define ZEND_VM_LINES\t\t" . ZEND_VM_LINES . "\n");
-       fputs($f, "#define ZEND_VM_KIND_CALL\t" . ZEND_VM_KIND_CALL . "\n");
-       fputs($f, "#define ZEND_VM_KIND_SWITCH\t" . ZEND_VM_KIND_SWITCH . "\n");
-       fputs($f, "#define ZEND_VM_KIND_GOTO\t" . ZEND_VM_KIND_GOTO . "\n");
-       fputs($f, "#define ZEND_VM_KIND_HYBRID\t" . ZEND_VM_KIND_HYBRID . "\n");
-       if ($GLOBALS["vm_kind_name"][ZEND_VM_KIND] === "ZEND_VM_KIND_HYBRID") {
-               fputs($f, "/* HYBRID requires support for computed GOTO and global register variables*/\n");
-               fputs($f, "#if (defined(__GNUC__) && defined(HAVE_GCC_GLOBAL_REGS))\n");
-               fputs($f, "# define ZEND_VM_KIND\t\tZEND_VM_KIND_HYBRID\n");
-               fputs($f, "#else\n");
-               fputs($f, "# define ZEND_VM_KIND\t\tZEND_VM_KIND_CALL\n");
-               fputs($f, "#endif\n");
-       } else {
-               fputs($f, "#define ZEND_VM_KIND\t\t" . $GLOBALS["vm_kind_name"][ZEND_VM_KIND] . "\n");
-       }
-       fputs($f, "\n");
-       foreach($vm_op_flags as $name => $val) {
-               fprintf($f, "#define %-24s 0x%08x\n", $name, $val);
-       }
-       fputs($f, "#define ZEND_VM_OP1_FLAGS(flags) (flags & 0xff)\n");
-       fputs($f, "#define ZEND_VM_OP2_FLAGS(flags) ((flags >> 8) & 0xff)\n");
-       fputs($f, "\n");
-       fputs($f, "BEGIN_EXTERN_C()\n\n");
-       fputs($f, "ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(zend_uchar opcode);\n");
-       fputs($f, "ZEND_API uint32_t ZEND_FASTCALL zend_get_opcode_flags(zend_uchar opcode);\n\n");
-       fputs($f, "END_EXTERN_C()\n\n");
-       foreach ($opcodes as $code => $dsc) {
-               $code = str_pad((string)$code,$code_len," ",STR_PAD_LEFT);
-               $op = str_pad($dsc["op"],$max_opcode_len);
-               if ($code <= $max_opcode) {
-                       fputs($f,"#define $op $code\n");
-               }
-       }
-       $code = str_pad((string)$max_opcode,$code_len," ",STR_PAD_LEFT);
-       $op = str_pad("ZEND_VM_LAST_OPCODE",$max_opcode_len);
-       fputs($f,"\n#define $op $code\n");
-       fputs($f, "\n#endif\n");
-       fclose($f);
-       echo "zend_vm_opcodes.h generated successfully.\n";
-       // zend_vm_opcodes.c
-       $f = fopen(__DIR__ . "/zend_vm_opcodes.c", "w+") or die("ERROR: Cannot create zend_vm_opcodes.c\n");
-       // Insert header
-       out($f, HEADER_TEXT);
-       fputs($f,"#include <stdio.h>\n");
-       fputs($f,"#include <zend.h>\n");
-       fputs($f,"#include <zend_vm_opcodes.h>\n\n");
-       fputs($f,"static const char *zend_vm_opcodes_names[".($max_opcode + 1)."] = {\n");
-       for ($i = 0; $i <= $max_opcode; $i++) {
-               fputs($f,"\t".(isset($opcodes[$i]["op"])?'"'.$opcodes[$i]["op"].'"':"NULL").",\n");
-       }
-       fputs($f, "};\n\n");
-       fputs($f,"static uint32_t zend_vm_opcodes_flags[".($max_opcode + 1)."] = {\n");
-       for ($i = 0; $i <= $max_opcode; $i++) {
-               fprintf($f, "\t0x%08x,\n", isset($opcodes[$i]["flags"]) ? $opcodes[$i]["flags"] : 0);
-       }
-       fputs($f, "};\n\n");
-       fputs($f, "ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(zend_uchar opcode) {\n");
-       fputs($f, "\tif (UNEXPECTED(opcode > ZEND_VM_LAST_OPCODE)) {\n");
-       fputs($f, "\t\treturn NULL;\n");
-       fputs($f, "\t}\n");
-       fputs($f, "\treturn zend_vm_opcodes_names[opcode];\n");
-       fputs($f, "}\n");
-       fputs($f, "ZEND_API uint32_t ZEND_FASTCALL zend_get_opcode_flags(zend_uchar opcode) {\n");
-       fputs($f, "\tif (UNEXPECTED(opcode > ZEND_VM_LAST_OPCODE)) {\n");
-       fputs($f, "\t\topcode = ZEND_NOP;\n");
-       fputs($f, "\t}\n");
-       fputs($f, "\treturn zend_vm_opcodes_flags[opcode];\n");
-       fputs($f, "}\n");
-       fclose($f);
-       echo "zend_vm_opcodes.c generated successfully.\n";
-       // Generate zend_vm_execute.h
-       $f = fopen(__DIR__ . "/zend_vm_execute.h", "w+") or die("ERROR: Cannot create zend_vm_execute.h\n");
-       $executor_file = realpath(__DIR__ . "/zend_vm_execute.h");
-       // Insert header
-       out($f, HEADER_TEXT);
-       out($f, "#ifdef ZEND_WIN32\n");
-       // Suppress free_op1 warnings on Windows
-       out($f, "# pragma warning(disable : 4101)\n");
-       if (ZEND_VM_SPEC) {
-               // Suppress (<non-zero constant> || <expression>) warnings on windows
-               out($f, "# pragma warning(once : 6235)\n");
-               // Suppress (<zero> && <expression>) warnings on windows
-               out($f, "# pragma warning(once : 6237)\n");
-               // Suppress (<non-zero constant> && <expression>) warnings on windows
-               out($f, "# pragma warning(once : 6239)\n");
-               // Suppress (<expression> && <non-zero constant>) warnings on windows
-               out($f, "# pragma warning(once : 6240)\n");
-               // Suppress (<non-zero constant> || <non-zero constant>) warnings on windows
-               out($f, "# pragma warning(once : 6285)\n");
-               // Suppress (<non-zero constant> || <expression>) warnings on windows
-               out($f, "# pragma warning(once : 6286)\n");
-               // Suppress constant with constant comparison warnings on windows
-               out($f, "# pragma warning(once : 6326)\n");
-       }
-       out($f, "#endif\n");
-       // Support for ZEND_USER_OPCODE
-       out($f, "static user_opcode_handler_t zend_user_opcode_handlers[256] = {\n");
-       for ($i = 0; $i < 255; ++$i) {
-               out($f, "\t(user_opcode_handler_t)NULL,\n");
-       }
-       out($f, "\t(user_opcode_handler_t)NULL\n};\n\n");
-       out($f, "static zend_uchar zend_user_opcodes[256] = {");
-       for ($i = 0; $i < 255; ++$i) {
-               if ($i % 16 == 1) out($f, "\n\t");
-               out($f, "$i,");
-       }
-       out($f, "255\n};\n\n");
-       // Generate specialized executor
-       gen_executor($f, $skl, ZEND_VM_SPEC, ZEND_VM_KIND, "execute", "zend_vm_init");
-       out($f, "\n");
-       // Generate zend_vm_get_opcode_handler() function
-       out($f, "static const uint32_t ZEND_FASTCALL zend_vm_get_opcode_handler_idx(uint32_t spec, const zend_op* op)\n");
-       out($f, "{\n");
-       if (!ZEND_VM_SPEC) {
-               out($f, "\treturn spec;\n");
-       } else {
-               out($f, "\tstatic const int zend_vm_decode[] = {\n");
-               out($f, "\t\t_UNUSED_CODE, /* 0 = IS_UNUSED  */\n");
-               out($f, "\t\t_CONST_CODE,  /* 1 = IS_CONST   */\n");
-               out($f, "\t\t_TMP_CODE,    /* 2 = IS_TMP_VAR */\n");
-               out($f, "\t\t_UNUSED_CODE, /* 3              */\n");
-               out($f, "\t\t_VAR_CODE,    /* 4 = IS_VAR     */\n");
-               out($f, "\t\t_UNUSED_CODE, /* 5              */\n");
-               out($f, "\t\t_UNUSED_CODE, /* 6              */\n");
-               out($f, "\t\t_UNUSED_CODE, /* 7              */\n");
-               out($f, "\t\t_CV_CODE      /* 8 = IS_CV      */\n");
-               out($f, "\t};\n");
-               out($f, "\tuint32_t offset = 0;\n");
-               out($f, "\tif (spec & SPEC_RULE_OP1) offset = offset * 5 + zend_vm_decode[op->op1_type];\n");
-               out($f, "\tif (spec & SPEC_RULE_OP2) offset = offset * 5 + zend_vm_decode[op->op2_type];\n");
-               if (isset($used_extra_spec["OP_DATA"]) ||
-                   isset($used_extra_spec["RETVAL"]) ||
-                   isset($used_extra_spec["QUICK_ARG"]) ||
-                   isset($used_extra_spec["SMART_BRANCH"]) ||
-                   isset($used_extra_spec["ISSET"])) {
-                       $else = "";
-                       out($f, "\tif (spec & SPEC_EXTRA_MASK) {\n");
-                       if (isset($used_extra_spec["RETVAL"])) {
-                               out($f, "\t\t{$else}if (spec & SPEC_RULE_RETVAL) {\n");
-                               out($f, "\t\t\toffset = offset * 2 + (op->result_type != IS_UNUSED);\n");
-                               $else = "} else ";
-                       }
-                       if (isset($used_extra_spec["QUICK_ARG"])) {
-                               out($f, "\t\t{$else}if (spec & SPEC_RULE_QUICK_ARG) {\n");
-                               out($f, "\t\t\toffset = offset * 2 + (op->op2.num <= MAX_ARG_FLAG_NUM);\n");
-                               $else = "} else ";
-                       }
-                       if (isset($used_extra_spec["OP_DATA"])) {
-                               out($f, "\t\t{$else}if (spec & SPEC_RULE_OP_DATA) {\n");
-                               out($f, "\t\t\toffset = offset * 5 + zend_vm_decode[(op + 1)->op1_type];\n");
-                               $else = "} else ";
-                       }
-                       if (isset($used_extra_spec["ISSET"])) {
-                               out($f, "\t\t{$else}if (spec & SPEC_RULE_ISSET) {\n");
-                               out($f, "\t\t\toffset = offset * 2 + (op->extended_value & ZEND_ISEMPTY);\n");
-                               $else = "} else ";
-                       }
-                       if (isset($used_extra_spec["SMART_BRANCH"])) {
-                               out($f, "\t\t{$else}if (spec & SPEC_RULE_SMART_BRANCH) {\n");
-                               out($f, "\t\t\toffset = offset * 3;\n");
-                               out($f, "\t\t\tif (op->result_type == (IS_SMART_BRANCH_JMPZ|IS_TMP_VAR)) {\n");
-                               out($f, "\t\t\t\toffset += 1;\n");
-                               out($f, "\t\t\t} else if (op->result_type == (IS_SMART_BRANCH_JMPNZ|IS_TMP_VAR)) {\n");
-                               out($f, "\t\t\t\toffset += 2;\n");
-                               out($f, "\t\t\t}\n");
-                               $else = "} else ";
-                       }
-                       if ($else !== "") {
-                               out($f, "\t\t}\n");
-                       }
-                       out($f, "\t}\n");
-               }
-               out($f, "\treturn (spec & SPEC_START_MASK) + offset;\n");
-       }
-       out($f, "}\n\n");
-       out($f, "#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC\n");
-       out($f, "static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op)\n");
-       out($f, "{\n");
-       if (!ZEND_VM_SPEC) {
-               out($f, "\treturn zend_opcode_handlers[zend_vm_get_opcode_handler_idx(opcode, op)];\n");
-       } else {
-               out($f, "\treturn zend_opcode_handlers[zend_vm_get_opcode_handler_idx(zend_spec_handlers[opcode], op)];\n");
-       }
-       out($f, "}\n");
-       out($f, "#endif\n\n");
-       if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
-               // Generate zend_vm_get_opcode_handler_func() function
-               out($f, "#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID\n");
-               out($f,"static const void *zend_vm_get_opcode_handler_func(zend_uchar opcode, const zend_op* op)\n");
-               out($f, "{\n");
-               out($f, "\tuint32_t spec = zend_spec_handlers[opcode];\n");
-               if (!ZEND_VM_SPEC) {
-                       out($f, "\treturn zend_opcode_handler_funcs[spec];\n");
-               } else {
-                       out($f, "\treturn zend_opcode_handler_funcs[zend_vm_get_opcode_handler_idx(spec, op)];\n");
-               }
-               out($f, "}\n\n");
-               out($f, "#endif\n\n");
-       }
-       // Generate zend_vm_get_opcode_handler() function
-       out($f, "ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler(zend_op* op)\n");
-       out($f, "{\n");
-       out($f, "\tzend_uchar opcode = zend_user_opcodes[op->opcode];\n");
-       if (!ZEND_VM_SPEC) {
-               out($f, "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_idx(opcode, op)];\n");
-       } else {
-               out($f, "\n");
-               out($f, "\tif (zend_spec_handlers[op->opcode] & SPEC_RULE_COMMUTATIVE) {\n");
-               out($f, "\t\tif (op->op1_type < op->op2_type) {\n");
-               out($f, "\t\t\tzend_swap_operands(op);\n");
-               out($f, "\t\t}\n");
-               out($f, "\t}\n");
-               out($f, "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_idx(zend_spec_handlers[opcode], op)];\n");
-       }
-       out($f, "}\n\n");
-       // Generate zend_vm_set_opcode_handler_ex() function
-       out($f, "ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint32_t op2_info, uint32_t res_info)\n");
-       out($f, "{\n");
-       out($f, "\tzend_uchar opcode = zend_user_opcodes[op->opcode];\n");
-       if (!ZEND_VM_SPEC) {
-               out($f, "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_idx(opcode, op)];\n");
-       } else {
-               out($f, "\tuint32_t spec = zend_spec_handlers[opcode];\n");
-               if (isset($used_extra_spec["TYPE"])) {
-                       out($f, "\tswitch (opcode) {\n");
-                       foreach($opcodes as $code => $dsc) {
-                               if (isset($dsc['type_spec'])) {
-                                       $orig_op = $dsc['op'];
-                                       out($f, "\t\tcase $orig_op:\n");
-                                       if (isset($dsc["spec"]["COMMUTATIVE"])) {
-                                               out($f, "\t\t\tif (op->op1_type < op->op2_type) {\n");
-                                               out($f, "\t\t\t\tzend_swap_operands(op);\n");
-                                               out($f, "\t\t\t}\n");
-                                       }
-                                       $first = true;
-                                       foreach($dsc['type_spec'] as $code => $condition) {
-                                               $condition = format_condition($condition);
-                                               if ($first) {
-                                                       out($f, "\t\t\tif $condition {\n");
-                                                       $first = false;
-                                               } else {
-                                                       out($f, "\t\t\t} else if $condition {\n");
-                                               }
-                                               $spec_dsc = $opcodes[$code];
-                                               if (isset($spec_dsc["spec"]["NO_CONST_CONST"])) {
-                                                       out($f, "\t\t\t\tif (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {\n");
-                                                       out($f, "\t\t\t\t\tbreak;\n");
-                                                       out($f, "\t\t\t\t}\n");
-                                               }
-                                               out($f, "\t\t\t\tspec = ${spec_dsc['spec_code']};\n");
-                                               if (isset($spec_dsc["spec"]["COMMUTATIVE"]) && !isset($dsc["spec"]["COMMUTATIVE"])) {
-                                                       out($f, "\t\t\t\tif (op->op1_type < op->op2_type) {\n");
-                                                       out($f, "\t\t\t\t\tzend_swap_operands(op);\n");
-                                                       out($f, "\t\t\t\t}\n");
-                                               }
-                                       }
-                                       if (!$first) {
-                                               out($f, "\t\t\t}\n");
-                                       }
-                                       out($f, "\t\t\tbreak;\n");
-                               }
-                       }
-                       $has_commutative = false;
-                       foreach($opcodes as $code => $dsc) {
-                               if (!isset($dsc['is_type_spec']) &&
-                                   !isset($dsc['type_spec']) &&
-                                   isset($dsc["spec"]["COMMUTATIVE"])) {
-                                       $orig_op = $dsc['op'];
-                                       out($f, "\t\tcase $orig_op:\n");
-                                       $has_commutative = true;
-                               }
-                       }
-                       if ($has_commutative) {
-                               out($f, "\t\t\tif (op->op1_type < op->op2_type) {\n");
-                               out($f, "\t\t\t\tzend_swap_operands(op);\n");
-                               out($f, "\t\t\t}\n");
-                               out($f, "\t\t\tbreak;\n");
-                               out($f, "\t\tcase ZEND_USER_OPCODE:\n");
-                               out($f, "\t\t\tif (zend_spec_handlers[op->opcode] & SPEC_RULE_COMMUTATIVE) {\n");
-                               out($f, "\t\t\t\tif (op->op1_type < op->op2_type) {\n");
-                               out($f, "\t\t\t\t\tzend_swap_operands(op);\n");
-                               out($f, "\t\t\t\t}\n");
-                               out($f, "\t\t\t}\n");
-                               out($f, "\t\t\tbreak;\n");
-                       }
-                       out($f, "\t\tdefault:\n");
-                       out($f, "\t\t\tbreak;\n");
-                       out($f, "\t}\n");
-               }
-               out($f, "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_idx(spec, op)];\n");
-       }
-       out($f, "}\n\n");
-       // Generate zend_vm_call_opcode_handler() function
-       if (ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
-               out($f, "ZEND_API int ZEND_FASTCALL zend_vm_call_opcode_handler(zend_execute_data* ex)\n");
-               out($f, "{\n");
-               if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
-                       out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
-                       out($f, "\topcode_handler_t handler;\n");
-                       out($f,"#endif\n");
-               }
-               out($f, "\tint ret;\n");
-               out($f, "#ifdef ZEND_VM_IP_GLOBAL_REG\n");
-               out($f, "\tconst zend_op *orig_opline = opline;\n");
-               out($f, "#endif\n");
-               out($f, "#ifdef ZEND_VM_FP_GLOBAL_REG\n");
-               out($f, "\tzend_execute_data *orig_execute_data = execute_data;\n");
-               out($f, "\texecute_data = ex;\n");
-               out($f, "#else\n");
-               out($f, "\tzend_execute_data *execute_data = ex;\n");
-               out($f, "#endif\n");
-               out($f, "\n");
-               out($f, "\tLOAD_OPLINE();\n");
-               out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
-               if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
-                       out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
-                       out($f, "\thandler = (opcode_handler_t)zend_vm_get_opcode_handler_func(zend_user_opcodes[opline->opcode], opline);\n");
-                       out($f, "\thandler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
-                       out($f, "\tif (EXPECTED(opline != &hybrid_halt_op)) {\n");
-                       out($f,"#else\n");
-               }
-               out($f, "\t((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
-               if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
-                       out($f, "\tif (EXPECTED(opline)) {\n");
-                       out($f,"#endif\n");
-               } else {
-                       out($f, "\tif (EXPECTED(opline)) {\n");
-               }
-               out($f, "\t\tret = execute_data != ex ? (int)(execute_data->prev_execute_data != ex) + 1 : 0;\n");
-               out($f, "\t\tSAVE_OPLINE();\n");
-               out($f, "\t} else {\n");
-               out($f, "\t\tret = -1;\n");
-               out($f, "\t}\n");
-               out($f, "#else\n");
-               out($f, "\tret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
-               out($f, "\tSAVE_OPLINE();\n");
-               out($f, "#endif\n");
-               out($f, "#ifdef ZEND_VM_FP_GLOBAL_REG\n");
-               out($f, "\texecute_data = orig_execute_data;\n");
-               out($f, "#endif\n");
-               out($f, "#ifdef ZEND_VM_IP_GLOBAL_REG\n");
-               out($f, "\topline = orig_opline;\n");
-               out($f, "#endif\n");
-               out($f, "\treturn ret;\n");
-               out($f, "}\n\n");
-       } else {
-               out($f, "ZEND_API int ZEND_FASTCALL zend_vm_call_opcode_handler(zend_execute_data* ex)\n");
-               out($f, "{\n");
-               out($f, "\tzend_error_noreturn(E_CORE_ERROR, \"zend_vm_call_opcode_handler() is not supported\");\n");
-               out($f, "\treturn 0;\n");
-               out($f, "}\n\n");
-       }
-       // Export handlers and helpers
-       if (count($export) > 0 &&
-           ZEND_VM_KIND != ZEND_VM_KIND_CALL) {
-               out($f,"#undef OPLINE\n");
-               out($f,"#undef DCL_OPLINE\n");
-               out($f,"#undef USE_OPLINE\n");
-               out($f,"#undef LOAD_OPLINE\n");
-               out($f,"#undef LOAD_OPLINE_EX\n");
-               out($f,"#undef LOAD_NEXT_OPLINE\n");
-               out($f,"#undef SAVE_OPLINE\n");
-               out($f,"#undef SAVE_OPLINE_EX\n");
-               out($f,"#define OPLINE EX(opline)\n");
-               out($f,"#define DCL_OPLINE\n");
-               out($f,"#define USE_OPLINE const zend_op *opline = EX(opline);\n");
-               out($f,"#define LOAD_OPLINE()\n");
-               out($f,"#define LOAD_OPLINE_EX()\n");
-               out($f,"#define LOAD_NEXT_OPLINE() ZEND_VM_INC_OPCODE()\n");
-               out($f,"#define SAVE_OPLINE()\n");
-               out($f,"#define SAVE_OPLINE_EX()\n");
-               out($f,"#undef HANDLE_EXCEPTION\n");
-               out($f,"#undef HANDLE_EXCEPTION_LEAVE\n");
-               out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
-               out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n");
-               out($f,"#undef ZEND_VM_CONTINUE\n");
-               out($f,"#undef ZEND_VM_RETURN\n");
-               out($f,"#undef ZEND_VM_ENTER_EX\n");
-               out($f,"#undef ZEND_VM_ENTER\n");
-               out($f,"#undef ZEND_VM_LEAVE\n");
-               out($f,"#undef ZEND_VM_DISPATCH\n");
-               out($f,"#define ZEND_VM_CONTINUE()   return  0\n");
-               out($f,"#define ZEND_VM_RETURN()     return -1\n");
-               out($f,"#define ZEND_VM_ENTER_EX()   return  1\n");
-               out($f,"#define ZEND_VM_ENTER()      return  1\n");
-               out($f,"#define ZEND_VM_LEAVE()      return  2\n");
-               out($f,"#define ZEND_VM_INTERRUPT()  return zend_interrupt_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
-               out($f,"#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n\n");
-               out($f,"\n");
-       }
-       foreach ($export as $dsk) {
-               list($kind, $func, $name) = $dsk;
-               out($f, "ZEND_API int $func(");
-               if ($kind == "handler") {
-                       out($f, "ZEND_OPCODE_HANDLER_ARGS)\n");
-                       $code = $opcodes[$opnames[$name]]['code'];
-               } else {
-                       $h = $helpers[$name];
-                       if ($h['param'] == null) {
-                               out($f, "ZEND_OPCODE_HANDLER_ARGS)\n");
-                       } else {
-                               out($f, $h['param']. " ZEND_OPCODE_HANDLER_ARGS_DC)\n");
-                       }
-                       $code = $h['code'];
-               }
-               $done = 0;
-               if (ZEND_VM_KIND == ZEND_VM_KIND_CALL) {
-                       if ($kind == "handler") {
-                               $op = $opcodes[$opnames[$name]];
-                               if (isset($op['op1']["ANY"]) && isset($op['op2']["ANY"])) {
-                                       out($f, "{\n\treturn ".$name.(ZEND_VM_SPEC?"_SPEC":"")."_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n}\n\n");
-                                       $done = 1;
-                               }
-                       } else if ($helpers[$name]["param"] == null) {
-                               $h = $helpers[$name];
-                               if (isset($h['op1']["ANY"]) && isset($h['op2']["ANY"])) {
-                                       out($f, "{\n\treturn ".$name.(ZEND_VM_SPEC?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n}\n\n");
-                                       $done = 1;
-                               }
-                       }
-               }
-               if (!$done) {
-                       gen_code($f, 0, ZEND_VM_KIND_CALL, 1, $code, 'ANY', 'ANY', $name);
-               }
-       }
-       fclose($f);
-       echo "zend_vm_execute.h generated successfully.\n";
+     global $definition_file, $skeleton_file, $executor_file,
+         $op_types, $list, $opcodes, $helpers, $params, $opnames,
+         $vm_op_flags, $used_extra_spec;
+     // Load definition file
+     $in = @file($def);
+     if (!$in) {
+         die("ERROR: Can not open definition file '$def'\n");
+     }
+     // We need absolute path to definition file to use it in #line directives
+     $definition_file = realpath($def);
+     // Load skeleton file
+     $skl = @file($skel);
+     if (!$skl) {
+         die("ERROR: Can not open skeleton file '$skel'\n");
+     }
+     // We need absolute path to skeleton file to use it in #line directives
+     $skeleton_file = realpath($skel);
+     // Parse definition file into tree
+     $lineno         = 0;
+     $handler        = null;
+     $helper         = null;
+     $max_opcode_len = 0;
+     $max_opcode     = 0;
+     $extra_num      = 256;
+     $export         = array();
+     foreach ($in as $line) {
+         ++$lineno;
+         if (strpos($line,"ZEND_VM_HANDLER(") === 0 ||
+             strpos($line,"ZEND_VM_INLINE_HANDLER(") === 0 ||
+             strpos($line,"ZEND_VM_HOT_HANDLER(") === 0 ||
+             strpos($line,"ZEND_VM_HOT_NOCONST_HANDLER(") === 0 ||
+             strpos($line,"ZEND_VM_HOT_NOCONSTCONST_HANDLER(") === 0 ||
+             strpos($line,"ZEND_VM_HOT_SEND_HANDLER(") === 0 ||
+             strpos($line,"ZEND_VM_HOT_OBJ_HANDLER(") === 0 ||
+             strpos($line,"ZEND_VM_COLD_HANDLER(") === 0 ||
+             strpos($line,"ZEND_VM_COLD_CONST_HANDLER(") === 0 ||
+             strpos($line,"ZEND_VM_COLD_CONSTCONST_HANDLER(") === 0) {
+           // Parsing opcode handler's definition
+             if (preg_match(
+                     "/^ZEND_VM_(HOT_|INLINE_|HOT_OBJ_|HOT_SEND_|HOT_NOCONST_|HOT_NOCONSTCONST_|COLD_|COLD_CONST_|COLD_CONSTCONST_)?HANDLER\(\s*([0-9]+)\s*,\s*([A-Z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/",
+                     $line,
+                     $m) == 0) {
+                 die("ERROR ($def:$lineno): Invalid ZEND_VM_HANDLER definition.\n");
+             }
+             $hot = !empty($m[1]) ? $m[1] : false;
+             $code = (int)$m[2];
+             $op   = $m[3];
+             $len  = strlen($op);
+             $op1  = parse_operand_spec($def, $lineno, $m[4], $flags1);
+             $op2  = parse_operand_spec($def, $lineno, $m[5], $flags2);
+             $flags = $flags1 | ($flags2 << 8);
+             if (!empty($m[7])) {
+                 $flags |= parse_ext_spec($def, $lineno, $m[7]);
+             }
+             if ($len > $max_opcode_len) {
+                 $max_opcode_len = $len;
+             }
+             if ($code > $max_opcode) {
+                 $max_opcode = $code;
+             }
+             if (isset($opcodes[$code])) {
+                 die("ERROR ($def:$lineno): Opcode with code '$code' is already defined.\n");
+             }
+             if (isset($opnames[$op])) {
+                 die("ERROR ($def:$lineno): Opcode with name '$op' is already defined.\n");
+             }
+             $opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>"","flags"=>$flags,"hot"=>$hot);
+             if (isset($m[9])) {
+                 $opcodes[$code]["spec"] = parse_spec_rules($def, $lineno, $m[9]);
+                 if (isset($opcodes[$code]["spec"]["NO_CONST_CONST"])) {
+                     $opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_NO_CONST_CONST"];
+                 }
+                 if (isset($opcodes[$code]["spec"]["COMMUTATIVE"])) {
+                     $opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_COMMUTATIVE"];
+                 }
+             }
+             $opnames[$op] = $code;
+             $handler = $code;
+             $helper = null;
+             $list[$lineno] = array("handler"=>$handler);
+         } else if (strpos($line,"ZEND_VM_TYPE_SPEC_HANDLER(") === 0 ||
+                    strpos($line,"ZEND_VM_INLINE_TYPE_SPEC_HANDLER(") === 0 ||
+                    strpos($line,"ZEND_VM_HOT_TYPE_SPEC_HANDLER(") === 0 ||
+                    strpos($line,"ZEND_VM_HOT_NOCONST_TYPE_SPEC_HANDLER(") === 0 ||
+                    strpos($line,"ZEND_VM_HOT_NOCONSTCONST_TYPE_SPEC_HANDLER(") === 0 ||
+                    strpos($line,"ZEND_VM_HOT_SEND_TYPE_SPEC_HANDLER(") === 0 ||
+                    strpos($line,"ZEND_VM_HOT_OBJ_TYPE_SPEC_HANDLER(") === 0) {
+           // Parsing opcode handler's definition
+             if (preg_match(
 -                    "/^ZEND_VM_(HOT_|INLINE_|HOT_OBJ_|HOT_SEND_|HOT_NOCONST_|HOT_NOCONSTCONST_)?TYPE_SPEC_HANDLER\(\s*([A-Z_]+)\s*,\s*((?:[^(,]|\([^()]*|(?R)*\))*),\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/",
++                    "/^ZEND_VM_(HOT_|INLINE_|HOT_OBJ_|HOT_SEND_|HOT_NOCONST_|HOT_NOCONSTCONST_)?TYPE_SPEC_HANDLER\(\s*([A-Z_|]+)\s*,\s*((?:[^(,]|\([^()]*|(?R)*\))*),\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/",
+                     $line,
+                     $m) == 0) {
+                 die("ERROR ($def:$lineno): Invalid ZEND_VM_TYPE_HANDLER_HANDLER definition.\n");
+             }
+             $hot = !empty($m[1]) ? $m[1] : false;
 -            $orig_op = $m[2];
 -            if (!isset($opnames[$orig_op])) {
 -                die("ERROR ($def:$lineno): Opcode with name '$orig_op' is not defined.\n");
 -            }
 -            $orig_code = $opnames[$orig_op];
 -            $condition = $m[3];
++            $orig_op_list = $m[2];
+             $code = $extra_num++;
++            foreach (explode('|', $orig_op_list) as $orig_op) {
++                if (!isset($opnames[$orig_op])) {
++                    die("ERROR ($def:$lineno): Opcode with name '$orig_op' is not defined.\n");
++                }
++                $orig_code = $opnames[$orig_op];
++                $condition = $m[3];
++                $opcodes[$orig_code]['type_spec'][$code] = $condition;
++            }
+             $op = $m[4];
+             $op1  = parse_operand_spec($def, $lineno, $m[5], $flags1);
+             $op2  = parse_operand_spec($def, $lineno, $m[6], $flags2);
+             $flags = $flags1 | ($flags2 << 8);
+             if (!empty($m[8])) {
+                 $flags |= parse_ext_spec($def, $lineno, $m[8]);
+             }
+             if (isset($opcodes[$code])) {
+                 die("ERROR ($def:$lineno): Opcode with name '$code' is already defined.\n");
+             }
 -            $opcodes[$orig_code]['type_spec'][$code] = $condition;
+             $used_extra_spec["TYPE"] = 1;
+             $opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>"","flags"=>$flags,"hot"=>$hot,"is_type_spec"=>true);
+             if (isset($m[10])) {
+                 $opcodes[$code]["spec"] = parse_spec_rules($def, $lineno, $m[10]);
+                 if (isset($opcodes[$code]["spec"]["NO_CONST_CONST"])) {
+                     $opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_NO_CONST_CONST"];
+                 }
+                 if (isset($opcodes[$code]["spec"]["COMMUTATIVE"])) {
+                     $opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_COMMUTATIVE"];
+                 }
+             }
+             $opnames[$op] = $code;
+             $handler = $code;
+             $helper = null;
+             $list[$lineno] = array("handler"=>$handler);
+         } else if (strpos($line,"ZEND_VM_HELPER(") === 0 ||
+                    strpos($line,"ZEND_VM_INLINE_HELPER(") === 0 ||
+                    strpos($line,"ZEND_VM_COLD_HELPER(") === 0 ||
+                    strpos($line,"ZEND_VM_HOT_HELPER(") === 0) {
+           // Parsing helper's definition
+             if (preg_match(
+                     "/^ZEND_VM(_INLINE|_COLD|_HOT)?_HELPER\(\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(?:,\s*SPEC\(([A-Z_|=,]+)\)\s*)?(?:,\s*([^)]*)\s*)?\)/",
+                     $line,
+                     $m) == 0) {
+                 die("ERROR ($def:$lineno): Invalid ZEND_VM_HELPER definition.\n");
+             }
+             $inline = !empty($m[1]) && $m[1] === "_INLINE";
+             $cold   = !empty($m[1]) && $m[1] === "_COLD";
+             $hot    = !empty($m[1]) && $m[1] === "_HOT";
+             $helper = $m[2];
+             $op1    = parse_operand_spec($def, $lineno, $m[3], $flags1);
+             $op2    = parse_operand_spec($def, $lineno, $m[4], $flags2);
+             $param  = isset($m[6]) ? $m[6] : null;
+             if (isset($helpers[$helper])) {
+                 die("ERROR ($def:$lineno): Helper with name '$helper' is already defined.\n");
+             }
+             // Store parameters
+             if (ZEND_VM_KIND == ZEND_VM_KIND_GOTO
+              || ZEND_VM_KIND == ZEND_VM_KIND_SWITCH
+              || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID && $hot)) {
+                 foreach (explode(",", $param) as $p) {
+                     $p = trim($p);
+                     if ($p !== "") {
+                         $params[$p] = 1;
+                     }
+                 }
+             }
+             $helpers[$helper] = array("op1"=>$op1,"op2"=>$op2,"param"=>$param,"code"=>"","inline"=>$inline,"cold"=>$cold,"hot"=>$hot);
+             if (!empty($m[5])) {
+                 $helpers[$helper]["spec"] = parse_spec_rules($def, $lineno, $m[5]);
+             }
+             $handler = null;
+             $list[$lineno] = array("helper"=>$helper);
+         } else if (strpos($line,"ZEND_VM_EXPORT_HANDLER(") === 0) {
+             if (preg_match(
+                     "/^ZEND_VM_EXPORT_HANDLER\(\s*([A-Za-z_]+)\s*,\s*([A-Z_]+)\s*\)/",
+                     $line,
+                     $m) == 0) {
+                 die("ERROR ($def:$lineno): Invalid ZEND_VM_EXPORT_HANDLER definition.\n");
+             }
+             if (!isset($opnames[$m[2]])) {
+                 die("ERROR ($def:$lineno): opcode '{$m[2]}' is not defined.\n");
+             }
+             $export[] = array("handler",$m[1],$m[2]);
+         } else if (strpos($line,"ZEND_VM_EXPORT_HELPER(") === 0) {
+             if (preg_match(
+                     "/^ZEND_VM_EXPORT_HELPER\(\s*([A-Za-z_]+)\s*,\s*([A-Za-z_]+)\s*\)/",
+                     $line,
+                     $m) == 0) {
+                 die("ERROR ($def:$lineno): Invalid ZEND_VM_EXPORT_HELPER definition.\n");
+             }
+             if (!isset($helpers[$m[2]])) {
+                 die("ERROR ($def:$lineno): helper '{$m[2]}' is not defined.\n");
+             }
+             $export[] = array("helper",$m[1],$m[2]);
+         } else if (strpos($line,"ZEND_VM_DEFINE_OP(") === 0) {
+             if (preg_match(
+                     "/^ZEND_VM_DEFINE_OP\(\s*([0-9]+)\s*,\s*([A-Z_]+)\s*\);/",
+                     $line,
+                     $m) == 0) {
+                 die("ERROR ($def:$lineno): Invalid ZEND_VM_DEFINE_OP definition.\n");
+             }
+             $code = (int)$m[1];
+             $op   = $m[2];
+             $len  = strlen($op);
+             if ($len > $max_opcode_len) {
+                 $max_opcode_len = $len;
+             }
+             if ($code > $max_opcode) {
+                 $max_opcode = $code;
+             }
+             if (isset($opcodes[$code])) {
+                 die("ERROR ($def:$lineno): Opcode with code '$code' is already defined.\n");
+             }
+             if (isset($opnames[$op])) {
+                 die("ERROR ($def:$lineno): Opcode with name '$op' is already defined.\n");
+             }
+             $opcodes[$code] = array("op"=>$op,"code"=>"");
+             $opnames[$op] = $code;
+         } else if ($handler !== null) {
+           // Add line of code to current opcode handler
+             $opcodes[$handler]["code"] .= $line;
+         } else if ($helper !== null) {
+           // Add line of code to current helper
+             $helpers[$helper]["code"] .= $line;
+         }
+     }
+     ksort($opcodes);
+     // Search for opcode handlers those are used by other opcode handlers
+     foreach ($opcodes as $dsc) {
+         if (preg_match("/^\s*{\s*ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)\s*;\s*}\s*/", $dsc["code"], $m)) {
+             $op = $m[1];
+             if (!isset($opnames[$op])) {
+                 die("ERROR ($def:$lineno): Opcode with name '$op' is not defined.\n");
+             }
+             $opcodes[$opnames[$dsc['op']]]['alias'] = $op;
+             if (!ZEND_VM_SPEC && ZEND_VM_KIND == ZEND_VM_KIND_SWITCH) {
+                 $code = $opnames[$op];
+                 $opcodes[$code]['use'] = 1;
+             }
+         } else if (preg_match_all("/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m", $dsc["code"], $mm, PREG_SET_ORDER)) {
+             foreach ($mm as $m) {
+                 $op = $m[1];
+                 if (!isset($opnames[$op])) {
+                     die("ERROR ($def:$lineno): Opcode with name '$op' is not defined.\n");
+                 }
+                 $code = $opnames[$op];
+                 $opcodes[$code]['use'] = 1;
+             }
+         }
+     }
+     // Generate opcode #defines (zend_vm_opcodes.h)
+     $code_len = strlen((string)$max_opcode);
+     $f = fopen(__DIR__ . "/zend_vm_opcodes.h", "w+") or die("ERROR: Cannot create zend_vm_opcodes.h\n");
+     // Insert header
+     out($f, HEADER_TEXT);
+     fputs($f, "#ifndef ZEND_VM_OPCODES_H\n#define ZEND_VM_OPCODES_H\n\n");
+     fputs($f, "#define ZEND_VM_SPEC\t\t" . ZEND_VM_SPEC . "\n");
+     fputs($f, "#define ZEND_VM_LINES\t\t" . ZEND_VM_LINES . "\n");
+     fputs($f, "#define ZEND_VM_KIND_CALL\t" . ZEND_VM_KIND_CALL . "\n");
+     fputs($f, "#define ZEND_VM_KIND_SWITCH\t" . ZEND_VM_KIND_SWITCH . "\n");
+     fputs($f, "#define ZEND_VM_KIND_GOTO\t" . ZEND_VM_KIND_GOTO . "\n");
+     fputs($f, "#define ZEND_VM_KIND_HYBRID\t" . ZEND_VM_KIND_HYBRID . "\n");
+     if ($GLOBALS["vm_kind_name"][ZEND_VM_KIND] === "ZEND_VM_KIND_HYBRID") {
+         fputs($f, "/* HYBRID requires support for computed GOTO and global register variables*/\n");
+         fputs($f, "#if (defined(__GNUC__) && defined(HAVE_GCC_GLOBAL_REGS))\n");
+         fputs($f, "# define ZEND_VM_KIND\t\tZEND_VM_KIND_HYBRID\n");
+         fputs($f, "#else\n");
+         fputs($f, "# define ZEND_VM_KIND\t\tZEND_VM_KIND_CALL\n");
+         fputs($f, "#endif\n");
+     } else {
+         fputs($f, "#define ZEND_VM_KIND\t\t" . $GLOBALS["vm_kind_name"][ZEND_VM_KIND] . "\n");
+     }
+     fputs($f, "\n");
+     foreach($vm_op_flags as $name => $val) {
+         fprintf($f, "#define %-24s 0x%08x\n", $name, $val);
+     }
+     fputs($f, "#define ZEND_VM_OP1_FLAGS(flags) (flags & 0xff)\n");
+     fputs($f, "#define ZEND_VM_OP2_FLAGS(flags) ((flags >> 8) & 0xff)\n");
+     fputs($f, "\n");
+     fputs($f, "BEGIN_EXTERN_C()\n\n");
+     fputs($f, "ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(zend_uchar opcode);\n");
+     fputs($f, "ZEND_API uint32_t ZEND_FASTCALL zend_get_opcode_flags(zend_uchar opcode);\n\n");
+     fputs($f, "END_EXTERN_C()\n\n");
+     foreach ($opcodes as $code => $dsc) {
+         $code = str_pad((string)$code,$code_len," ",STR_PAD_LEFT);
+         $op = str_pad($dsc["op"],$max_opcode_len);
+         if ($code <= $max_opcode) {
+             fputs($f,"#define $op $code\n");
+         }
+     }
+     $code = str_pad((string)$max_opcode,$code_len," ",STR_PAD_LEFT);
+     $op = str_pad("ZEND_VM_LAST_OPCODE",$max_opcode_len);
+     fputs($f,"\n#define $op $code\n");
+     fputs($f, "\n#endif\n");
+     fclose($f);
+     echo "zend_vm_opcodes.h generated successfully.\n";
+     // zend_vm_opcodes.c
+     $f = fopen(__DIR__ . "/zend_vm_opcodes.c", "w+") or die("ERROR: Cannot create zend_vm_opcodes.c\n");
+     // Insert header
+     out($f, HEADER_TEXT);
+     fputs($f,"#include <stdio.h>\n");
+     fputs($f,"#include <zend.h>\n");
+     fputs($f,"#include <zend_vm_opcodes.h>\n\n");
+     fputs($f,"static const char *zend_vm_opcodes_names[".($max_opcode + 1)."] = {\n");
+     for ($i = 0; $i <= $max_opcode; $i++) {
+         fputs($f,"\t".(isset($opcodes[$i]["op"])?'"'.$opcodes[$i]["op"].'"':"NULL").",\n");
+     }
+     fputs($f, "};\n\n");
+     fputs($f,"static uint32_t zend_vm_opcodes_flags[".($max_opcode + 1)."] = {\n");
+     for ($i = 0; $i <= $max_opcode; $i++) {
+         fprintf($f, "\t0x%08x,\n", isset($opcodes[$i]["flags"]) ? $opcodes[$i]["flags"] : 0);
+     }
+     fputs($f, "};\n\n");
+     fputs($f, "ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(zend_uchar opcode) {\n");
+     fputs($f, "\tif (UNEXPECTED(opcode > ZEND_VM_LAST_OPCODE)) {\n");
+     fputs($f, "\t\treturn NULL;\n");
+     fputs($f, "\t}\n");
+     fputs($f, "\treturn zend_vm_opcodes_names[opcode];\n");
+     fputs($f, "}\n");
+     fputs($f, "ZEND_API uint32_t ZEND_FASTCALL zend_get_opcode_flags(zend_uchar opcode) {\n");
+     fputs($f, "\tif (UNEXPECTED(opcode > ZEND_VM_LAST_OPCODE)) {\n");
+     fputs($f, "\t\topcode = ZEND_NOP;\n");
+     fputs($f, "\t}\n");
+     fputs($f, "\treturn zend_vm_opcodes_flags[opcode];\n");
+     fputs($f, "}\n");
+     fclose($f);
+     echo "zend_vm_opcodes.c generated successfully.\n";
+     // Generate zend_vm_execute.h
+     $f = fopen(__DIR__ . "/zend_vm_execute.h", "w+") or die("ERROR: Cannot create zend_vm_execute.h\n");
+     $executor_file = realpath(__DIR__ . "/zend_vm_execute.h");
+     // Insert header
+     out($f, HEADER_TEXT);
+     out($f, "#ifdef ZEND_WIN32\n");
+     // Suppress free_op1 warnings on Windows
+     out($f, "# pragma warning(disable : 4101)\n");
+     if (ZEND_VM_SPEC) {
+         // Suppress (<non-zero constant> || <expression>) warnings on windows
+         out($f, "# pragma warning(once : 6235)\n");
+         // Suppress (<zero> && <expression>) warnings on windows
+         out($f, "# pragma warning(once : 6237)\n");
+         // Suppress (<non-zero constant> && <expression>) warnings on windows
+         out($f, "# pragma warning(once : 6239)\n");
+         // Suppress (<expression> && <non-zero constant>) warnings on windows
+         out($f, "# pragma warning(once : 6240)\n");
+         // Suppress (<non-zero constant> || <non-zero constant>) warnings on windows
+         out($f, "# pragma warning(once : 6285)\n");
+         // Suppress (<non-zero constant> || <expression>) warnings on windows
+         out($f, "# pragma warning(once : 6286)\n");
+         // Suppress constant with constant comparison warnings on windows
+         out($f, "# pragma warning(once : 6326)\n");
+     }
+     out($f, "#endif\n");
+     // Support for ZEND_USER_OPCODE
+     out($f, "static user_opcode_handler_t zend_user_opcode_handlers[256] = {\n");
+     for ($i = 0; $i < 255; ++$i) {
+         out($f, "\t(user_opcode_handler_t)NULL,\n");
+     }
+     out($f, "\t(user_opcode_handler_t)NULL\n};\n\n");
+     out($f, "static zend_uchar zend_user_opcodes[256] = {");
+     for ($i = 0; $i < 255; ++$i) {
+         if ($i % 16 == 1) out($f, "\n\t");
+         out($f, "$i,");
+     }
+     out($f, "255\n};\n\n");
+     // Generate specialized executor
+     gen_executor($f, $skl, ZEND_VM_SPEC, ZEND_VM_KIND, "execute", "zend_vm_init");
+     out($f, "\n");
+     // Generate zend_vm_get_opcode_handler() function
 -    out($f, "static const void* ZEND_FASTCALL zend_vm_get_opcode_handler_ex(uint32_t spec, const zend_op* op)\n");
++    out($f, "static const uint32_t ZEND_FASTCALL zend_vm_get_opcode_handler_idx(uint32_t spec, const zend_op* op)\n");
+     out($f, "{\n");
+     if (!ZEND_VM_SPEC) {
 -        out($f, "\treturn zend_opcode_handlers[spec];\n");
++        out($f, "\treturn spec;\n");
+     } else {
+         out($f, "\tstatic const int zend_vm_decode[] = {\n");
+         out($f, "\t\t_UNUSED_CODE, /* 0 = IS_UNUSED  */\n");
+         out($f, "\t\t_CONST_CODE,  /* 1 = IS_CONST   */\n");
+         out($f, "\t\t_TMP_CODE,    /* 2 = IS_TMP_VAR */\n");
+         out($f, "\t\t_UNUSED_CODE, /* 3              */\n");
+         out($f, "\t\t_VAR_CODE,    /* 4 = IS_VAR     */\n");
+         out($f, "\t\t_UNUSED_CODE, /* 5              */\n");
+         out($f, "\t\t_UNUSED_CODE, /* 6              */\n");
+         out($f, "\t\t_UNUSED_CODE, /* 7              */\n");
+         out($f, "\t\t_CV_CODE      /* 8 = IS_CV      */\n");
+         out($f, "\t};\n");
+         out($f, "\tuint32_t offset = 0;\n");
+         out($f, "\tif (spec & SPEC_RULE_OP1) offset = offset * 5 + zend_vm_decode[op->op1_type];\n");
+         out($f, "\tif (spec & SPEC_RULE_OP2) offset = offset * 5 + zend_vm_decode[op->op2_type];\n");
+         if (isset($used_extra_spec["OP_DATA"]) ||
+             isset($used_extra_spec["RETVAL"]) ||
+             isset($used_extra_spec["QUICK_ARG"]) ||
+             isset($used_extra_spec["SMART_BRANCH"]) ||
+             isset($used_extra_spec["ISSET"])) {
+             $else = "";
+             out($f, "\tif (spec & SPEC_EXTRA_MASK) {\n");
+             if (isset($used_extra_spec["RETVAL"])) {
+                 out($f, "\t\t{$else}if (spec & SPEC_RULE_RETVAL) {\n");
+                 out($f, "\t\t\toffset = offset * 2 + (op->result_type != IS_UNUSED);\n");
+                 $else = "} else ";
+             }
+             if (isset($used_extra_spec["QUICK_ARG"])) {
+                 out($f, "\t\t{$else}if (spec & SPEC_RULE_QUICK_ARG) {\n");
+                 out($f, "\t\t\toffset = offset * 2 + (op->op2.num <= MAX_ARG_FLAG_NUM);\n");
+                 $else = "} else ";
+             }
+             if (isset($used_extra_spec["OP_DATA"])) {
+                 out($f, "\t\t{$else}if (spec & SPEC_RULE_OP_DATA) {\n");
+                 out($f, "\t\t\toffset = offset * 5 + zend_vm_decode[(op + 1)->op1_type];\n");
+                 $else = "} else ";
+             }
+             if (isset($used_extra_spec["ISSET"])) {
+                 out($f, "\t\t{$else}if (spec & SPEC_RULE_ISSET) {\n");
+                 out($f, "\t\t\toffset = offset * 2 + (op->extended_value & ZEND_ISEMPTY);\n");
+                 $else = "} else ";
+             }
+             if (isset($used_extra_spec["SMART_BRANCH"])) {
+                 out($f, "\t\t{$else}if (spec & SPEC_RULE_SMART_BRANCH) {\n");
+                 out($f,       "\t\t\toffset = offset * 3;\n");
 -                out($f, "\t\t\tif ((op+1)->opcode == ZEND_JMPZ) {\n");
++                out($f, "\t\t\tif (op->result_type == (IS_SMART_BRANCH_JMPZ|IS_TMP_VAR)) {\n");
+                 out($f,       "\t\t\t\toffset += 1;\n");
 -                out($f, "\t\t\t} else if ((op+1)->opcode == ZEND_JMPNZ) {\n");
++                out($f, "\t\t\t} else if (op->result_type == (IS_SMART_BRANCH_JMPNZ|IS_TMP_VAR)) {\n");
+                 out($f,       "\t\t\t\toffset += 2;\n");
+                 out($f, "\t\t\t}\n");
+                 $else = "} else ";
+             }
+             if ($else !== "") {
+                 out($f, "\t\t}\n");
+             }
+             out($f, "\t}\n");
+         }
 -        out($f, "\treturn zend_opcode_handlers[(spec & SPEC_START_MASK) + offset];\n");
++        out($f, "\treturn (spec & SPEC_START_MASK) + offset;\n");
+     }
+     out($f, "}\n\n");
+     out($f, "#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC\n");
+     out($f, "static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op)\n");
+     out($f, "{\n");
+     if (!ZEND_VM_SPEC) {
 -        out($f, "\treturn zend_vm_get_opcode_handler_ex(opcode, op);\n");
++        out($f, "\treturn zend_opcode_handlers[zend_vm_get_opcode_handler_idx(opcode, op)];\n");
+     } else {
 -        out($f, "\treturn zend_vm_get_opcode_handler_ex(zend_spec_handlers[opcode], op);\n");
++        out($f, "\treturn zend_opcode_handlers[zend_vm_get_opcode_handler_idx(zend_spec_handlers[opcode], op)];\n");
+     }
+     out($f, "}\n");
+     out($f, "#endif\n\n");
+     if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
+         // Generate zend_vm_get_opcode_handler_func() function
+         out($f, "#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID\n");
+         out($f,"static const void *zend_vm_get_opcode_handler_func(zend_uchar opcode, const zend_op* op)\n");
+         out($f, "{\n");
 -            out($f, "\tuint32_t spec = zend_spec_handlers[opcode];\n");
++        out($f, "\tuint32_t spec = zend_spec_handlers[opcode];\n");
+         if (!ZEND_VM_SPEC) {
+             out($f, "\treturn zend_opcode_handler_funcs[spec];\n");
+         } else {
 -            out($f, "\tstatic const int zend_vm_decode[] = {\n");
 -            out($f, "\t\t_UNUSED_CODE, /* 0 = IS_UNUSED  */\n");
 -            out($f, "\t\t_CONST_CODE,  /* 1 = IS_CONST   */\n");
 -            out($f, "\t\t_TMP_CODE,    /* 2 = IS_TMP_VAR */\n");
 -            out($f, "\t\t_UNUSED_CODE, /* 3              */\n");
 -            out($f, "\t\t_VAR_CODE,    /* 4 = IS_VAR     */\n");
 -            out($f, "\t\t_UNUSED_CODE, /* 5              */\n");
 -            out($f, "\t\t_UNUSED_CODE, /* 6              */\n");
 -            out($f, "\t\t_UNUSED_CODE, /* 7              */\n");
 -            out($f, "\t\t_CV_CODE      /* 8 = IS_CV      */\n");
 -            out($f, "\t};\n");
 -            out($f, "\tuint32_t offset = 0;\n");
 -            out($f, "\tif (spec & SPEC_RULE_OP1) offset = offset * 5 + zend_vm_decode[op->op1_type];\n");
 -            out($f, "\tif (spec & SPEC_RULE_OP2) offset = offset * 5 + zend_vm_decode[op->op2_type];\n");
 -
 -            if (isset($used_extra_spec["OP_DATA"]) ||
 -                isset($used_extra_spec["RETVAL"]) ||
 -                isset($used_extra_spec["QUICK_ARG"]) ||
 -                isset($used_extra_spec["SMART_BRANCH"]) ||
 -                isset($used_extra_spec["ISSET"])) {
 -
 -                $else = "";
 -                out($f, "\tif (spec & SPEC_EXTRA_MASK) {\n");
 -
 -                if (isset($used_extra_spec["OP_DATA"])) {
 -                    out($f, "\t\t{$else}if (spec & SPEC_RULE_OP_DATA) offset = offset * 5 + zend_vm_decode[(op + 1)->op1_type];\n");
 -                    $else = "else ";
 -                }
 -                if (isset($used_extra_spec["RETVAL"])) {
 -                    out($f, "\t\t{$else}if (spec & SPEC_RULE_RETVAL) offset = offset * 2 + (op->result_type != IS_UNUSED);\n");
 -                    $else = "else ";
 -                }
 -                if (isset($used_extra_spec["QUICK_ARG"])) {
 -                    out($f, "\t\t{$else}if (spec & SPEC_RULE_QUICK_ARG) offset = offset * 2 + (op->op2.num <= MAX_ARG_FLAG_NUM);\n");
 -                    $else = "else ";
 -                }
 -                if (isset($used_extra_spec["SMART_BRANCH"])) {
 -                    out($f, "\t\t{$else}if (spec & SPEC_RULE_SMART_BRANCH) {\n");
 -                    out($f,   "\t\t\toffset = offset * 3;\n");
 -                    out($f, "\t\t\tif ((op+1)->opcode == ZEND_JMPZ) {\n");
 -                    out($f,   "\t\t\t\toffset += 1;\n");
 -                    out($f, "\t\t\t} else if ((op+1)->opcode == ZEND_JMPNZ) {\n");
 -                    out($f,   "\t\t\t\toffset += 2;\n");
 -                    out($f, "\t\t\t}\n");
 -                    out($f, "\t\t}\n");
 -                    $else = "else ";
 -                }
 -                if (isset($used_extra_spec["ISSET"])) {
 -                    out($f, "\t\t{$else}if (spec & SPEC_RULE_ISSET) offset = offset * 2 + (op->extended_value & ZEND_ISEMPTY);\n");
 -                    $else = "else ";
 -                }
 -                out($f, "\t}\n");
 -            }
 -
 -            out($f, "\treturn zend_opcode_handler_funcs[(spec & SPEC_START_MASK) + offset];\n");
++            out($f, "\treturn zend_opcode_handler_funcs[zend_vm_get_opcode_handler_idx(spec, op)];\n");
+         }
+         out($f, "}\n\n");
+         out($f, "#endif\n\n");
+     }
+     // Generate zend_vm_get_opcode_handler() function
+     out($f, "ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler(zend_op* op)\n");
+     out($f, "{\n");
+     out($f, "\tzend_uchar opcode = zend_user_opcodes[op->opcode];\n");
+     if (!ZEND_VM_SPEC) {
 -        out($f, "\top->handler = zend_vm_get_opcode_handler(opcode, op);\n");
++        out($f, "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_idx(opcode, op)];\n");
+     } else {
+         out($f, "\n");
+         out($f, "\tif (zend_spec_handlers[op->opcode] & SPEC_RULE_COMMUTATIVE) {\n");
+         out($f, "\t\tif (op->op1_type < op->op2_type) {\n");
+         out($f, "\t\t\tzend_swap_operands(op);\n");
+         out($f, "\t\t}\n");
+         out($f, "\t}\n");
 -        out($f, "\top->handler = zend_vm_get_opcode_handler_ex(zend_spec_handlers[opcode], op);\n");
++        out($f, "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_idx(zend_spec_handlers[opcode], op)];\n");
+     }
+     out($f, "}\n\n");
+     // Generate zend_vm_set_opcode_handler_ex() function
+     out($f, "ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint32_t op2_info, uint32_t res_info)\n");
+     out($f, "{\n");
+     out($f, "\tzend_uchar opcode = zend_user_opcodes[op->opcode];\n");
+     if (!ZEND_VM_SPEC) {
 -        out($f, "\top->handler = zend_vm_get_opcode_handler_ex(opcode, op);\n");
++        out($f, "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_idx(opcode, op)];\n");
+     } else {
+         out($f, "\tuint32_t spec = zend_spec_handlers[opcode];\n");
+         if (isset($used_extra_spec["TYPE"])) {
+             out($f, "\tswitch (opcode) {\n");
+             foreach($opcodes as $code => $dsc) {
+                 if (isset($dsc['type_spec'])) {
+                     $orig_op = $dsc['op'];
+                     out($f, "\t\tcase $orig_op:\n");
+                     if (isset($dsc["spec"]["COMMUTATIVE"])) {
+                         out($f, "\t\t\tif (op->op1_type < op->op2_type) {\n");
+                         out($f, "\t\t\t\tzend_swap_operands(op);\n");
+                         out($f, "\t\t\t}\n");
+                     }
+                     $first = true;
+                     foreach($dsc['type_spec'] as $code => $condition) {
+                         $condition = format_condition($condition);
+                         if ($first) {
+                             out($f, "\t\t\tif $condition {\n");
+                             $first = false;
+                         } else {
+                             out($f, "\t\t\t} else if $condition {\n");
+                         }
+                         $spec_dsc = $opcodes[$code];
+                         if (isset($spec_dsc["spec"]["NO_CONST_CONST"])) {
+                             out($f, "\t\t\t\tif (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {\n");
+                             out($f, "\t\t\t\t\tbreak;\n");
+                             out($f, "\t\t\t\t}\n");
+                         }
+                         out($f, "\t\t\t\tspec = ${spec_dsc['spec_code']};\n");
+                         if (isset($spec_dsc["spec"]["COMMUTATIVE"]) && !isset($dsc["spec"]["COMMUTATIVE"])) {
+                             out($f, "\t\t\t\tif (op->op1_type < op->op2_type) {\n");
+                             out($f, "\t\t\t\t\tzend_swap_operands(op);\n");
+                             out($f, "\t\t\t\t}\n");
+                         }
+                     }
+                     if (!$first) {
+                         out($f, "\t\t\t}\n");
+                     }
+                     out($f, "\t\t\tbreak;\n");
+                 }
+             }
+             $has_commutative = false;
+             foreach($opcodes as $code => $dsc) {
+                 if (!isset($dsc['is_type_spec']) &&
+                     !isset($dsc['type_spec']) &&
+                     isset($dsc["spec"]["COMMUTATIVE"])) {
+                     $orig_op = $dsc['op'];
+                     out($f, "\t\tcase $orig_op:\n");
+                     $has_commutative = true;
+                 }
+             }
+             if ($has_commutative) {
+                 out($f, "\t\t\tif (op->op1_type < op->op2_type) {\n");
+                 out($f, "\t\t\t\tzend_swap_operands(op);\n");
+                 out($f, "\t\t\t}\n");
+                 out($f, "\t\t\tbreak;\n");
+                 out($f, "\t\tcase ZEND_USER_OPCODE:\n");
+                 out($f, "\t\t\tif (zend_spec_handlers[op->opcode] & SPEC_RULE_COMMUTATIVE) {\n");
+                 out($f, "\t\t\t\tif (op->op1_type < op->op2_type) {\n");
+                 out($f, "\t\t\t\t\tzend_swap_operands(op);\n");
+                 out($f, "\t\t\t\t}\n");
+                 out($f, "\t\t\t}\n");
+                 out($f, "\t\t\tbreak;\n");
+             }
+             out($f, "\t\tdefault:\n");
+             out($f, "\t\t\tbreak;\n");
+             out($f, "\t}\n");
+         }
 -        out($f, "\top->handler = zend_vm_get_opcode_handler_ex(spec, op);\n");
++        out($f, "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_idx(spec, op)];\n");
+     }
+     out($f, "}\n\n");
+     // Generate zend_vm_call_opcode_handler() function
+     if (ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
+         out($f, "ZEND_API int ZEND_FASTCALL zend_vm_call_opcode_handler(zend_execute_data* ex)\n");
+         out($f, "{\n");
+         if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
+             out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+             out($f, "\topcode_handler_t handler;\n");
+             out($f,"#endif\n");
+         }
+         out($f, "\tint ret;\n");
+         out($f, "#ifdef ZEND_VM_IP_GLOBAL_REG\n");
+         out($f, "\tconst zend_op *orig_opline = opline;\n");
+         out($f, "#endif\n");
+         out($f, "#ifdef ZEND_VM_FP_GLOBAL_REG\n");
+         out($f, "\tzend_execute_data *orig_execute_data = execute_data;\n");
+         out($f, "\texecute_data = ex;\n");
+         out($f, "#else\n");
+         out($f, "\tzend_execute_data *execute_data = ex;\n");
+         out($f, "#endif\n");
+         out($f, "\n");
+         out($f, "\tLOAD_OPLINE();\n");
+         out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
+         if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
+             out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+             out($f, "\thandler = (opcode_handler_t)zend_vm_get_opcode_handler_func(zend_user_opcodes[opline->opcode], opline);\n");
+             out($f, "\thandler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
+             out($f, "\tif (EXPECTED(opline != &hybrid_halt_op)) {\n");
+             out($f,"#else\n");
+         }
+         out($f, "\t((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
+         if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) {
+             out($f, "\tif (EXPECTED(opline)) {\n");
+             out($f,"#endif\n");
+         } else {
+             out($f, "\tif (EXPECTED(opline)) {\n");
+         }
+         out($f, "\t\tret = execute_data != ex ? (int)(execute_data->prev_execute_data != ex) + 1 : 0;\n");
+         out($f, "\t\tSAVE_OPLINE();\n");
+         out($f, "\t} else {\n");
+         out($f, "\t\tret = -1;\n");
+         out($f, "\t}\n");
+         out($f, "#else\n");
+         out($f, "\tret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
+         out($f, "\tSAVE_OPLINE();\n");
+         out($f, "#endif\n");
+         out($f, "#ifdef ZEND_VM_FP_GLOBAL_REG\n");
+         out($f, "\texecute_data = orig_execute_data;\n");
+         out($f, "#endif\n");
+         out($f, "#ifdef ZEND_VM_IP_GLOBAL_REG\n");
+         out($f, "\topline = orig_opline;\n");
+         out($f, "#endif\n");
+         out($f, "\treturn ret;\n");
+         out($f, "}\n\n");
+     } else {
+         out($f, "ZEND_API int ZEND_FASTCALL zend_vm_call_opcode_handler(zend_execute_data* ex)\n");
+         out($f, "{\n");
+         out($f, "\tzend_error_noreturn(E_CORE_ERROR, \"zend_vm_call_opcode_handler() is not supported\");\n");
+         out($f, "\treturn 0;\n");
+         out($f, "}\n\n");
+     }
+     // Export handlers and helpers
+     if (count($export) > 0 &&
+         ZEND_VM_KIND != ZEND_VM_KIND_CALL) {
+         out($f,"#undef OPLINE\n");
+         out($f,"#undef DCL_OPLINE\n");
+         out($f,"#undef USE_OPLINE\n");
+         out($f,"#undef LOAD_OPLINE\n");
+         out($f,"#undef LOAD_OPLINE_EX\n");
+         out($f,"#undef LOAD_NEXT_OPLINE\n");
+         out($f,"#undef SAVE_OPLINE\n");
+         out($f,"#undef SAVE_OPLINE_EX\n");
+         out($f,"#define OPLINE EX(opline)\n");
+         out($f,"#define DCL_OPLINE\n");
+         out($f,"#define USE_OPLINE const zend_op *opline = EX(opline);\n");
+         out($f,"#define LOAD_OPLINE()\n");
+         out($f,"#define LOAD_OPLINE_EX()\n");
+         out($f,"#define LOAD_NEXT_OPLINE() ZEND_VM_INC_OPCODE()\n");
+         out($f,"#define SAVE_OPLINE()\n");
+         out($f,"#define SAVE_OPLINE_EX()\n");
+         out($f,"#undef HANDLE_EXCEPTION\n");
+         out($f,"#undef HANDLE_EXCEPTION_LEAVE\n");
+         out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
+         out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n");
+         out($f,"#undef ZEND_VM_CONTINUE\n");
+         out($f,"#undef ZEND_VM_RETURN\n");
+         out($f,"#undef ZEND_VM_ENTER_EX\n");
+         out($f,"#undef ZEND_VM_ENTER\n");
+         out($f,"#undef ZEND_VM_LEAVE\n");
+         out($f,"#undef ZEND_VM_DISPATCH\n");
+         out($f,"#define ZEND_VM_CONTINUE()   return  0\n");
+         out($f,"#define ZEND_VM_RETURN()     return -1\n");
+         out($f,"#define ZEND_VM_ENTER_EX()   return  1\n");
+         out($f,"#define ZEND_VM_ENTER()      return  1\n");
+         out($f,"#define ZEND_VM_LEAVE()      return  2\n");
+         out($f,"#define ZEND_VM_INTERRUPT()  return zend_interrupt_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
+         out($f,"#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n\n");
+         out($f,"\n");
+     }
+     foreach ($export as $dsk) {
+         list($kind, $func, $name) = $dsk;
+         out($f, "ZEND_API int $func(");
+         if ($kind == "handler") {
+             out($f, "ZEND_OPCODE_HANDLER_ARGS)\n");
+             $code = $opcodes[$opnames[$name]]['code'];
+         } else {
+             $h = $helpers[$name];
+             if ($h['param'] == null) {
+                 out($f, "ZEND_OPCODE_HANDLER_ARGS)\n");
+             } else {
+                 out($f, $h['param']. " ZEND_OPCODE_HANDLER_ARGS_DC)\n");
+             }
+             $code = $h['code'];
+         }
+         $done = 0;
+         if (ZEND_VM_KIND == ZEND_VM_KIND_CALL) {
+             if ($kind == "handler") {
+                 $op = $opcodes[$opnames[$name]];
+                 if (isset($op['op1']["ANY"]) && isset($op['op2']["ANY"])) {
+                     out($f, "{\n\treturn ".$name.(ZEND_VM_SPEC?"_SPEC":"")."_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n}\n\n");
+                     $done = 1;
+                 }
+             } else if ($helpers[$name]["param"] == null) {
+                 $h = $helpers[$name];
+                 if (isset($h['op1']["ANY"]) && isset($h['op2']["ANY"])) {
+                     out($f, "{\n\treturn ".$name.(ZEND_VM_SPEC?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n}\n\n");
+                     $done = 1;
+                 }
+             }
+         }
+         if (!$done) {
+             gen_code($f, 0, ZEND_VM_KIND_CALL, 1, $code, 'ANY', 'ANY', $name);
+         }
+     }
+     fclose($f);
+     echo "zend_vm_execute.h generated successfully.\n";
  }
  
  function usage() {
index 43734a2a6762cc7d1b575262ec8cfe02a9fd9427,ee274d10c3d48f7f979ea21ab174b76b0bd3c534..5c6835940fd5d2a157f340295463efa686ba59af
@@@ -132,25 -134,25 +132,25 @@@ function task($label, $callback) 
  /* {{{ print_success
   */
  function print_success() {
-       global $options;
-       if (PHP_OS_FAMILY != 'Windows') {
-               $file_prefix = './';
-               $make_prefix = '';
-       } else {
-               $file_prefix = '';
-               $make_prefix = 'n';
-       }
-       printf('%1$sSuccess. The extension is now ready to be compiled. To do so, use the%s', PHP_EOL);
-       printf('following steps:%1$s%1$s', PHP_EOL);
-       printf('cd /path/to/php-src/ext/%s%s', $options['ext'], PHP_EOL);
-       printf('phpize%s', PHP_EOL);
-       printf('%sconfigure%s', $file_prefix, PHP_EOL);
-       printf('%smake%2$s%2$s', $make_prefix, PHP_EOL);
-       printf('Don\'t forget to run tests once the compilation is done:%s', PHP_EOL);
-       printf('%smake test%2$s%2$s', $make_prefix, PHP_EOL);
-       printf('Thank you for using PHP!%s', PHP_EOL);
+     global $options;
+     if (PHP_OS_FAMILY != 'Windows') {
+         $file_prefix = './';
+         $make_prefix = '';
+     } else {
+         $file_prefix = '';
+         $make_prefix = 'n';
+     }
+     printf('%1$sSuccess. The extension is now ready to be compiled. To do so, use the%s', PHP_EOL);
+     printf('following steps:%1$s%1$s', PHP_EOL);
 -    printf('cd /path/to/php-src/%s%s', $options['ext'], PHP_EOL);
++    printf('cd /path/to/php-src/ext/%s%s', $options['ext'], PHP_EOL);
+     printf('phpize%s', PHP_EOL);
+     printf('%sconfigure%s', $file_prefix, PHP_EOL);
+     printf('%smake%2$s%2$s', $make_prefix, PHP_EOL);
+     printf('Don\'t forget to run tests once the compilation is done:%s', PHP_EOL);
+     printf('%smake test%2$s%2$s', $make_prefix, PHP_EOL);
+     printf('Thank you for using PHP!%s', PHP_EOL);
  }
  /* }}} */
  
@@@ -240,27 -242,29 +240,27 @@@ function process_args($argv, $argc) 
  /* {{{ process_source_tags
   */
  function process_source_tags($file, $short_name) {
-       global $options;
+     global $options;
  
-       $source = file_get_contents($file);
+     $source = file_get_contents($file);
  
-       if ($source === false) {
-               error('Unable to open file for reading: ' . $short_name);
-       }
+     if ($source === false) {
+         error('Unable to open file for reading: ' . $short_name);
+     }
  
-       $source = str_replace('%EXTNAME%', $options['ext'], $source);
-       $source = str_replace('%EXTNAMECAPS%', strtoupper($options['ext']), $source);
+     $source = str_replace('%EXTNAME%', $options['ext'], $source);
+     $source = str_replace('%EXTNAMECAPS%', strtoupper($options['ext']), $source);
  
-       if (strpos($short_name, '.c') !== false || strpos($short_name, '.h') !== false) {
-               static $header;
+     if (strpos($short_name, '.c') !== false || strpos($short_name, '.h') !== false) {
+         static $header;
  
-               if (!$header) {
-                       if ($options['std']) {
-                               $author_len = strlen($options['author']);
-                               $credits = $options['author'] . ($author_len && $author_len <= 60 ? str_repeat(' ', 60 - $author_len) : '');
+         if (!$header) {
+             if ($options['std']) {
+                 $author_len = strlen($options['author']);
+                 $credits = $options['author'] . ($author_len && $author_len <= 60 ? str_repeat(' ', 60 - $author_len) : '');
  
-                               $header = <<<"HEADER"
+                 $header = <<<"HEADER"
  /*
 -   +----------------------------------------------------------------------+
 -   | PHP Version 7                                                        |
     +----------------------------------------------------------------------+
     | Copyright (c) The PHP Group                                          |
     +----------------------------------------------------------------------+
@@@ -326,21 -330,20 +326,21 @@@ function copy_config_scripts() 
  /* {{{ copy_sources
   */
  function copy_sources() {
-       global $options;
+     global $options;
  
-       $files = [
-                       'skeleton.c'            => $options['ext'] . '.c',
-                       'skeleton.stub.php'     => $options['ext'] . '.stub.php',
-                       'php_skeleton.h'        => 'php_' . $options['ext'] . '.h'
-                       ];
+     $files = [
+             'skeleton.c'              => $options['ext'] . '.c',
++            'skeleton.stub.php'       => $options['ext'] . '.stub.php',
+             'php_skeleton.h'  => 'php_' . $options['ext'] . '.h'
+             ];
  
-       foreach ($files as $src_file => $dst_file) {
-               if (!copy($options['skel'] . $src_file, $options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $dst_file)) {
-                       error('Unable to copy source file: ' . $src_file);
-               }
+     foreach ($files as $src_file => $dst_file) {
+         if (!copy($options['skel'] . $src_file, $options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $dst_file)) {
+             error('Unable to copy source file: ' . $src_file);
+         }
  
-               process_source_tags($options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $dst_file, $dst_file);
-       }
+         process_source_tags($options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $dst_file, $dst_file);
+     }
  }
  /* }}} */
  
index 812217f99010d6ebf9d74a58697125b839fd4eb5,0000000000000000000000000000000000000000..ff73d2e12464f4fcec53d41e65d8c890182fd606
mode 100644,000000..100644
--- /dev/null
@@@ -1,96 -1,0 +1,96 @@@
-     /** 
 +<?php
 +
 +class FFI
 +{
 +    /** @return ?FFI */
 +    static function cdef(string $code = UNKNOWN, string $lib = UNKNOWN) {}
 +
 +    /** @return ?FFI */
 +    static function load(string $filename) {}
 +
 +    /** @return ?FFI */
 +    static function scope(string $scope_name) {}
 +
 +    /**
 +     * @param FFI\CType|string $type
 +     * @return ?FFI\CData
 +     */
 +    static function new($type, bool $owned = true, bool $persistent = false) {}
 +
-     /** 
++    /**
 +     * @prefer-ref $ptr
 +     * @return void
 +     */
 +    static function free(FFI\CData $ptr) {}
 +
++    /**
 +     * @param FFI\CType|string $type
 +     * @prefer-ref $ptr
 +     * @return ?FFI\CData
 +     */
 +    static function cast($type, $ptr) {}
 +
 +    /** @return ?FFI\CType */
 +    static function type(string $type) {}
 +
 +    /**
 +     * @prefer-ref $ptr
 +     * @return FFI\CType
 +     */
 +    static function typeof(FFI\CData $ptr) {}
 +
 +    /** @return ?FFI\CType */
 +    static function arrayType(FFI\CType $type, array $dims) {}
 +
 +    /**
 +     * @prefer-ref $ptr
 +     * @return FFI\CData
 +     */
 +    static function addr(FFI\CData $ptr) {}
 +
 +    /**
 +     * @prefer-ref $ptr
 +     * @return ?int
 +     */
 +    static function sizeof(object $ptr) {}
 +
 +    /**
 +     * @prefer-ref $ptr
 +     * @return ?int
 +     */
 +    static function alignof(object $ptr) {}
 +
 +    /**
 +     * @prefer-ref $dst
 +     * @prefer-ref $src
 +     * @param string|FFI\CData $dst
 +     * @return void
 +     */
 +    static function memcpy(FFI\CData $dst, $src, int $size) {}
 +
 +    /**
 +     * @prefer-ref $ptr1
 +     * @param string|FFI\CData $ptr1
 +     * @prefer-ref $ptr2
 +     * @param string|FFI\CData $ptr2
 +     * @return ?int
 +     */
 +    static function memcmp($ptr1, $ptr2, int $size) {}
 +
 +    /**
 +     * @prefer-ref $ptr
 +     * @return void
 +     */
 +    static function memset(FFI\CData $ptr, int $ch, int $size) {}
 +
 +    /**
 +     * @prefer-ref $ptr
 +     * @return ?string
 +     */
 +    static function string(FFI\CData $ptr, int $size = UNKNOWN) {}
 +
 +    /**
 +     * @prefer-ref $ptr
 +     */
 +    static function isNull(FFI\CData $ptr) {}
 +}
Simple merge
Simple merge
Simple merge
index a1719fddb97dfcbf88eed25c6a2a3ca724da7ccc,0000000000000000000000000000000000000000..2af9d5bc5e6f9f18681133b17106ebf6f5eeea83
mode 100644,000000..100644
--- /dev/null
@@@ -1,422 -1,0 +1,422 @@@
-     /** 
 +<?php
 +
 +class Phar extends RecursiveDirectoryIterator implements Countable, ArrayAccess
 +{
 +    public function __construct(string $filename, int $flags = FilesystemIterator::SKIP_DOTS|FilesystemIterator::UNIX_PATHS, ?string $alias = null) {}
 +
 +    public function __destruct() {}
 +
 +    /** @return void */
 +    public function addEmptyDir(string $dirname) {}
 +
 +    /** @return void */
 +    public function addFile(string $filename, string $localname = UNKNOWN) {}
 +
 +    /** @return void */
 +    public function addFromString(string $localname, string $contents) {}
 +
 +    /** @return array|false */
 +    public function buildFromDirectory(string $base_dir, string $regex = UNKNOWN) {}
 +
 +    /** @return array|false */
 +    public function buildFromIterator(Traversable $iterator, string $base_directory = UNKNOWN) {}
 +
 +    /** @return void */
 +    public function compressFiles(int $compression_type) {}
 +
 +    /** @return bool */
 +    public function decompressFiles() {}
 +
 +    /** @return ?Phar */
 +    public function compress(int $compression_type, string $file_ext = UNKNOWN) {}
 +
 +    /** @return ?Phar */
 +    public function decompress(string $file_ext = UNKNOWN) {}
 +
 +    /** @return ?Phar */
 +    public function convertToExecutable(int $format = 9021976, int $compression_type = 9021976, string $file_ext = UNKNOWN) {}
 +
 +    /** @return ?Phar */
 +    public function convertToData(int $format = 9021976, int $compression_type = 9021976, string $file_ext = UNKNOWN) {}
 +
 +    /** @return bool */
 +    public function copy(string $newfile, string $oldfile) {}
 +
 +    /** @return int */
 +    public function count(int $mode = UNKNOWN) {}
 +
 +    /** @return bool */
 +    public function delete(string $entry) {}
 +
 +    /** @return bool */
 +    public function delMetadata() {}
 +
 +    /** @return bool */
 +    public function extractTo(string $pathto, $files = null, bool $overwrite = false) {}
 +
 +    /** @return ?string */
 +    public function getAlias() {}
 +
 +    /** @return string */
 +    public function getPath() {}
 +
 +    /** @return mixed */
 +    public function getMetadata() {}
 +
 +    /** @return bool */
 +    public function getModified() {}
 +
 +    /** @return array|false */
 +    public function getSignature() {}
 +
 +    /** @return string */
 +    public function getStub() {}
 +
 +    /** @return string */
 +    public function getVersion() {}
 +
 +    /** @return bool */
 +    public function hasMetadata() {}
 +
 +    /** @return bool */
 +    public function isBuffering() {}
 +
 +    /** @return int|false */
 +    public function isCompressed() {}
 +
 +    /** @return bool */
 +    public function isFileFormat(int $fileformat) {}
 +
 +    /** @return bool */
 +    public function isWritable() {}
 +
 +    /**
 +     * @param string $entry
 +     * @return bool
 +     */
 +    public function offsetExists($entry) {}
 +
-     /** 
++    /**
 +     * @param string $entry
 +     * @return PharFileInfo
 +     */
 +    public function offsetGet($entry) {}
 +
 +    /**
 +     * @param string $entry
 +     * @param resource|string $value
 +     * @return void
 +     */
 +    public function offsetSet($entry, $value) {}
 +
 +    /**
 +     * @param string $entry
 +     * @return bool
 +     */
 +    public function offsetUnset($entry) {}
 +
 +    /** @return bool */
 +    public function setAlias(string $alias) {}
 +
 +    /** @return bool */
 +    public function setDefaultStub(?string $index = null, string $webindex = UNKNOWN) {}
 +
 +    /**
 +     * @param mixed $metadata
 +     * @return void
 +     */
 +    public function setMetadata($metadata) {}
 +
 +    /** @return void */
 +    public function setSignatureAlgorithm(int $algorithm, string $privatekey = UNKNOWN) {}
 +
-     /** 
++    /**
 +     * @param resource $newstub
 +     * @return bool
 +     */
 +    public function setStub($newstub, $maxlen = -1) {}
 +
 +    /** @return void */
 +    public function startBuffering() {}
 +
 +    /** @return void */
 +    public function stopBuffering() {}
 +
 +    /** @return string */
 +    final public static function apiVersion() {}
 +
 +    /** @return bool */
 +    final public static function canCompress(int $method = 0) {}
 +
 +    /** @return bool */
 +    final public static function canWrite() {}
 +
 +    /** @return string */
 +    final public static function createDefaultStub(string $index = UNKNOWN, string $webindex = UNKNOWN) {}
 +
 +    /** @return array */
 +    final public static function getSupportedCompression() {}
 +
 +    /** @return array */
 +    final public static function getSupportedSignatures() {}
 +
 +    /** @return void */
 +    final public static function interceptFileFuncs() {}
 +
 +    /** @return bool */
 +    final public static function isValidPharFilename(string $filename, bool $executable = true) {}
 +
 +    /** @return bool */
 +    final public static function loadPhar(string $filename, ?string $alias = null) {}
 +
 +    /** @return bool */
 +    final public static function mapPhar(?string $alias = null, int $offset = 0) {}
 +
 +    /** @return string */
 +    final public static function running(bool $retphar = true) {}
 +
 +    /** @return void */
 +    final public static function mount(string $inphar, string $externalfile) {}
 +
 +    /** @return void */
 +    final public static function mungServer(array $munglist) {}
 +
 +    /** @return bool */
 +    final public static function unlinkArchive(string $archive) {}
 +
 +    /** @return void */
 +    final public static function webPhar(?string $alias = null, ?string $index = null, string $f404 = UNKNOWN, array $mimetypes = [], $rewrites = UNKNOWN) {}
 +}
 +
 +class PharData extends RecursiveDirectoryIterator implements Countable, ArrayAccess
 +{
 +    public function __construct(string $filename, int $flags = FilesystemIterator::SKIP_DOTS|FilesystemIterator::UNIX_PATHS, ?string $alias = null, $fileformat = 0) {}
 +
 +    public function __destruct() {}
 +
 +    /** @return void */
 +    public function addEmptyDir(string $dirname) {}
 +
 +    /** @return void */
 +    public function addFile(string $filename, string $localname = UNKNOWN) {}
 +
 +    /** @return void */
 +    public function addFromString(string $localname, string $contents) {}
 +
 +    /** @return array|false */
 +    public function buildFromDirectory(string $base_dir, string $regex = UNKNOWN) {}
 +
 +    /** @return array|false */
 +    public function buildFromIterator(Traversable $iterator, string $base_directory = UNKNOWN) {}
 +
 +    /** @return void */
 +    public function compressFiles(int $compression_type) {}
 +
 +    /** @return bool */
 +    public function decompressFiles() {}
 +
 +    /** @return ?Phar */
 +    public function compress(int $compression_type, string $file_ext = UNKNOWN) {}
 +
 +    /** @return ?Phar */
 +    public function decompress(string $file_ext = UNKNOWN) {}
 +
 +    /** @return ?Phar */
 +    public function convertToExecutable(int $format = 9021976, int $compression_type = 9021976, string $file_ext = UNKNOWN) {}
 +
 +    /** @return ?Phar */
 +    public function convertToData(int $format = 9021976, int $compression_type = 9021976, string $file_ext = UNKNOWN) {}
 +
 +    /** @return bool */
 +    public function copy(string $newfile, string $oldfile) {}
 +
 +    /** @return int */
 +    public function count(int $mode = UNKNOWN) {}
 +
 +    /** @return bool */
 +    public function delete(string $entry) {}
 +
 +    /** @return bool */
 +    public function delMetadata() {}
 +
 +    /** @return bool */
 +    public function extractTo(string $pathto, $files = null, bool $overwrite = false) {}
 +
 +    /** @return ?string */
 +    public function getAlias() {}
 +
 +    /** @return string */
 +    public function getPath() {}
 +
 +    /** @return mixed */
 +    public function getMetadata() {}
 +
 +    /** @return bool */
 +    public function getModified() {}
 +
 +    /** @return array|false */
 +    public function getSignature() {}
 +
 +    /** @return string */
 +    public function getStub() {}
 +
 +    /** @return string */
 +    public function getVersion() {}
 +
 +    /** @return bool */
 +    public function hasMetadata() {}
 +
 +    /** @return bool */
 +    public function isBuffering() {}
 +
 +    /** @return int|false */
 +    public function isCompressed() {}
 +
 +    /** @return bool */
 +    public function isFileFormat(int $fileformat) {}
 +
 +    /** @return bool */
 +    public function isWritable() {}
 +
 +    /**
 +     * @param string $entry
 +     * @return bool
 +     */
 +    public function offsetExists($entry) {}
 +
 +    /**
 +     * @param string $entry
 +     * @return PharFileInfo
 +     */
 +    public function offsetGet($entry) {}
 +
 +    /**
 +     * @param string $entry
 +     * @param resource|string $value
 +     * @return void
 +     */
 +    public function offsetSet($entry, $value) {}
 +
 +    /**
 +     * @param string $entry
 +     * @return bool
 +     */
 +    public function offsetUnset($entry) {}
 +
 +    /** @return bool */
 +    public function setAlias(string $alias) {}
 +
 +    /** @return bool */
 +    public function setDefaultStub(?string $index = null, string $webindex = UNKNOWN) {}
 +
 +    /**
 +     * @param mixed $metadata
 +     * @return void
 +     */
 +    public function setMetadata($metadata) {}
 +
 +    /** @return void */
 +    public function setSignatureAlgorithm(int $algorithm, string $privatekey = UNKNOWN) {}
 +
++    /**
 +     * @param resource $newstub
 +     * @return bool
 +     */
 +    public function setStub($newstub, $maxlen = -1) {}
 +
 +    /** @return void */
 +    public function startBuffering() {}
 +
 +    /** @return void */
 +    public function stopBuffering() {}
 +
 +    /** @return string */
 +    final public static function apiVersion() {}
 +
 +    /** @return bool */
 +    final public static function canCompress(int $method = 0) {}
 +
 +    /** @return bool */
 +    final public static function canWrite() {}
 +
 +    /** @return string */
 +    final public static function createDefaultStub(string $index = UNKNOWN, string $webindex = UNKNOWN) {}
 +
 +    /** @return array */
 +    final public static function getSupportedCompression() {}
 +
 +    /** @return array */
 +    final public static function getSupportedSignatures() {}
 +
 +    /** @return void */
 +    final public static function interceptFileFuncs() {}
 +
 +    /** @return bool */
 +    final public static function isValidPharFilename(string $filename, bool $executable = true) {}
 +
 +    /** @return bool */
 +    final public static function loadPhar(string $filename, ?string $alias = null) {}
 +
 +    /** @return bool */
 +    final public static function mapPhar(?string $alias = null, int $offset = 0) {}
 +
 +    /** @return string */
 +    final public static function running(bool $retphar = true) {}
 +
 +    /** @return void */
 +    final public static function mount(string $inphar, string $externalfile) {}
 +
 +    /** @return void */
 +    final public static function mungServer(array $munglist) {}
 +
 +    /** @return bool */
 +    final public static function unlinkArchive(string $archive) {}
 +
 +    /** @return void */
 +    final public static function webPhar(?string $alias = null, ?string $index = null, string $f404 = UNKNOWN, array $mimetypes = [], $rewrites = UNKNOWN) {}
 +}
 +
 +class PharFileInfo extends SplFileInfo
 +{
 +    public function __construct(string $filename) {}
 +
 +    public function __destruct() {}
 +
 +    /** @return void */
 +    public function chmod(int $perms) {}
 +
 +    /** @return bool */
 +    public function compress(int $compression_type) {}
 +
 +    /** @return bool */
 +    public function decompress() {}
 +
 +    /** @return bool */
 +    public function delMetadata() {}
 +
 +    /** @return int */
 +    public function getCompressedSize() {}
 +
 +    /** @return int */
 +    public function getCRC32() {}
 +
 +    /** @return string */
 +    public function getContent() {}
 +
 +    public function getMetadata() {}
 +
 +    /** @return int */
 +    public function getPharFlags() {}
 +
 +    /** @return bool */
 +    public function hasMetadata() {}
 +
 +    /** @return bool */
 +    public function isCompressed($compression_type = 9021976) {}
 +
 +    /** @return bool */
 +    public function isCRCChecked() {}
 +
 +    /** @return void */
 +    public function setMetadata($metadata) {}
 +}
index 965a0fbc8dd4451fad8508cfe6fe6c9773a30ce3,0000000000000000000000000000000000000000..ce085637be1be112588c8f1ebd2e8d2d11a7b593
mode 100644,000000..100644
--- /dev/null
@@@ -1,120 -1,0 +1,120 @@@
-       function __construct(int $version, string $host, string $community, int $timeout = UNKNOWN, int $retries = UNKNOWN) {}
-       /** @return bool */
-       function close() {}
-       /** @return bool */
-       function setSecurity(string $sec_level, string $auth_protocol = '', string $auth_passphrase = '', string $priv_protocol = '', string $priv_passphrase = '', string $contextName = '', string $contextEngineID = '') {}
-       /**
-        * @param array|string $object_id
-        * @return array|bool
-        */
-       function get($object_id, bool $use_orignames = false) {}
-       /**
-        * @param array|string $object_id
-        * @return array|bool
-        */
-       function getnext($object_id) {}
-       /**
-        * @param array|string $object_id
-        * @return array|bool
-        */
-       function walk($object_id, bool $suffix_keys = false, int $max_repetitions = UNKNOWN, int $non_repeaters = UNKNOWN) {}
-       /**
-        * @param array|string $object_id
-        * @param array|string $type
-        * @param array|string $value
-        * @return array|bool
-        */
-       function set($object_id, $type, $value) {}
-       /** @return int */
-       function getErrno() {}
-       /** @return string */
-       function getError() {}
 +<?php
 +
 +/** @param array|string $object_id */
 +function snmpget(string $host, string $community, $object_id, int $timeout = UNKNOWN, int $retries = UNKNOWN): array|bool {}
 +
 +/** @param array|string $object_id */
 +function snmpgetnext(string $host, string $community, $object_id, int $timeout = UNKNOWN, int $retries = UNKNOWN): array|bool {}
 +
 +/** @param array|string $object_id */
 +function snmpwalk(string $host, string $community, $object_id, int $timeout = UNKNOWN, int $retries = UNKNOWN): array|bool {}
 +
 +/** @param array|string $object_id */
 +function snmprealwalk(string $host, string $community, $object_id, int $timeout = UNKNOWN, int $retries = UNKNOWN): array|bool {}
 +
 +/** @param array|string $object_id */
 +function snmpwalkoid(string $host, string $community, $object_id, int $timeout = UNKNOWN, int $retries = UNKNOWN): array|bool {}
 +
 +/**
 + * @param array|string $object_id
 + * @param array|string $type
 + * @param array|string $value
 + */
 +function snmpset(string $host, string $community, $object_id, $type, $value, int $timeout = UNKNOWN, int $retries = UNKNOWN): array|bool {}
 +
 +function snmp_get_quick_print(): bool {}
 +
 +function snmp_set_quick_print(int $quick_print): bool {}
 +
 +function snmp_set_enum_print(int $enum_print): bool {}
 +
 +function snmp_set_oid_output_format(int $oid_format): bool {}
 +
 +function snmp_set_oid_numeric_print(int $oid_format): bool {}
 +
 +/** @param array|string $object_id */
 +function snmp2_get(string $host, string $community, $object_id, int $timeout = UNKNOWN, int $retries = UNKNOWN): array|bool {}
 +
 +/** @param array|string $object_id */
 +function snmp2_getnext(string $host, string $community, $object_id, int $timeout = UNKOWN, int $retries = UNKNOWN): array|bool {}
 +
 +/** @param array|string $object_id */
 +function snmp2_walk(string $host, string $community, $object_id, int $timeout = UNKNOWN, int $retries = UNKNOWN): array|bool {}
 +
 +/** @param array|string $object_id */
 +function snmp2_real_walk(string $host, string $community, $object_id, int $timeout = UNKNOWN, int $retries = UNKNOWN): array|bool {}
 +
 +/**
 + * @param array|string $object_id
 + * @param array|string $type
 + * @param array|string $value
 + */
 +function snmp2_set(string $host, string $community, $object_id, $type, $value, int $timeout = UNKNOWN, int $retries = UNKNOWN): array|bool {}
 +
 +/** @param array|string $object_id */
 +function snmp3_get(string $host, string $sec_name, string $sec_level, string $auth_protocol, string $auth_passphrase, string $priv_protocol, string $priv_passphrase, $object_id, int $timeout = UNKNOWN, int $retries = UNKNOWN): array|bool {}
 +
 +/** @param array|string $object_id */
 +function snmp3_getnext(string $host, string $sec_name, string $sec_level, string $auth_protocol, string $auth_passphrase, string $priv_protocol, string $priv_passphrase, $object_id, int $timeout = UNKNOWN, int $retries = UNKOWN): array|bool {}
 +
 +/** @param array|string $object_id */
 +function snmp3_walk(string $host, string $sec_name, string $sec_level, string $auth_protocol, string $auth_passphrase, string $priv_protocol, string $priv_passphrase, $object_id, int $timeout = UNKNOWN, int $retries = UNKNOWN): array|bool {}
 +
 +/** @param array|string $object_id */
 +function snmp3_real_walk(string $host, string $sec_name, string $sec_level, string $auth_protocol, string $auth_passphrase, string $priv_protocol, string $priv_passphrase, $object_id, int $timeout = UNKNOWN, int $retries = UNKNOWN): array|bool {}
 +
 +/**
 + * @param array|string $object_id
 + * @param array|string $type
 + * @param array|string $value
 + */
 +function snmp3_set(string $host, string $sec_name, string $sec_level, string $auth_protocol, string $auth_passphrase, string $priv_protocol, string $priv_passphrase, $object_id, $type, $value, int $timeout = UNKNOWN, int $retries = UNKNOWN): array|bool {}
 +
 +function snmp_set_valueretrieval(int $method): bool {}
 +
 +function snmp_get_valueretrieval(): int {}
 +
 +function snmp_read_mib(string $filename): bool {}
 +
 +class SNMP
 +{
++    function __construct(int $version, string $host, string $community, int $timeout = UNKNOWN, int $retries = UNKNOWN) {}
++
++    /** @return bool */
++    function close() {}
++
++    /** @return bool */
++    function setSecurity(string $sec_level, string $auth_protocol = '', string $auth_passphrase = '', string $priv_protocol = '', string $priv_passphrase = '', string $contextName = '', string $contextEngineID = '') {}
++
++    /**
++     * @param array|string $object_id
++     * @return array|bool
++     */
++    function get($object_id, bool $use_orignames = false) {}
++
++    /**
++     * @param array|string $object_id
++     * @return array|bool
++     */
++    function getnext($object_id) {}
++
++    /**
++     * @param array|string $object_id
++     * @return array|bool
++     */
++    function walk($object_id, bool $suffix_keys = false, int $max_repetitions = UNKNOWN, int $non_repeaters = UNKNOWN) {}
++
++    /**
++     * @param array|string $object_id
++     * @param array|string $type
++     * @param array|string $value
++     * @return array|bool
++     */
++    function set($object_id, $type, $value) {}
++
++    /** @return int */
++    function getErrno() {}
++
++    /** @return string */
++    function getError() {}
 +}
Simple merge
diff --cc run-tests.php
index a5698882db8ced8a44935c323801e4d66a598f84,1b1735411147a5a84a4344c3ede584d6c4fffe06..1a59ca5f8e7fb1e03d1c29fd79ac1d5f72b74e37
   */
  function main()
  {
-       /* This list was derived in a naïve mechanical fashion. If a member
-        * looks like it doesn't belong, it probably doesn't; cull at will.
-        */
-       global $DETAILED, $PHP_FAILED_TESTS, $SHOW_ONLY_GROUPS, $argc, $argv, $cfg,
-                  $cfgfiles, $cfgtypes, $conf_passed, $end_time, $environment,
-                  $exts_skipped, $exts_tested, $exts_to_test, $failed_tests_file,
-                  $html_file, $html_output, $ignored_by_ext, $ini_overwrites, $is_switch,
-                  $just_save_results, $log_format, $matches, $no_clean, $no_file_cache,
-                  $optionals, $output_file, $pass_option_n, $pass_options,
-                  $pattern_match, $php, $php_cgi, $phpdbg, $preload, $redir_tests,
-                  $repeat, $result_tests_file, $slow_min_ms, $start_time, $switch,
-                  $temp_source, $temp_target, $temp_urlbase, $test_cnt, $test_dirs,
-                  $test_files, $test_idx, $test_list, $test_results, $testfile,
-                  $user_tests, $valgrind, $sum_results, $shuffle;
-       // Parallel testing
-       global $workers, $workerID;
-       define('IS_WINDOWS', substr(PHP_OS, 0, 3) == "WIN");
-       $workerID = 0;
-       if (getenv("TEST_PHP_WORKER")) {
-               $workerID = intval(getenv("TEST_PHP_WORKER"));
-               run_worker();
-               return;
-       }
-       define('INIT_DIR', getcwd());
-       // change into the PHP source directory.
-       if (getenv('TEST_PHP_SRCDIR')) {
-               @chdir(getenv('TEST_PHP_SRCDIR'));
-       }
-       define('TEST_PHP_SRCDIR', getcwd());
-       if (!function_exists('proc_open')) {
-               echo <<<NO_PROC_OPEN_ERROR
+     /* This list was derived in a naïve mechanical fashion. If a member
+      * looks like it doesn't belong, it probably doesn't; cull at will.
+      */
+     global $DETAILED, $PHP_FAILED_TESTS, $SHOW_ONLY_GROUPS, $argc, $argv, $cfg,
+            $cfgfiles, $cfgtypes, $conf_passed, $end_time, $environment,
+            $exts_skipped, $exts_tested, $exts_to_test, $failed_tests_file,
+            $html_file, $html_output, $ignored_by_ext, $ini_overwrites, $is_switch,
+            $just_save_results, $log_format, $matches, $no_clean, $no_file_cache,
+            $optionals, $output_file, $pass_option_n, $pass_options,
+            $pattern_match, $php, $php_cgi, $phpdbg, $preload, $redir_tests,
+            $repeat, $result_tests_file, $slow_min_ms, $start_time, $switch,
+            $temp_source, $temp_target, $temp_urlbase, $test_cnt, $test_dirs,
+            $test_files, $test_idx, $test_list, $test_results, $testfile,
+            $user_tests, $valgrind, $sum_results, $shuffle;
+     // Parallel testing
+     global $workers, $workerID;
++    define('IS_WINDOWS', substr(PHP_OS, 0, 3) == "WIN");
++
+     $workerID = 0;
+     if (getenv("TEST_PHP_WORKER")) {
+         $workerID = intval(getenv("TEST_PHP_WORKER"));
+         run_worker();
+         return;
+     }
+     define('INIT_DIR', getcwd());
+     // change into the PHP source directory.
+     if (getenv('TEST_PHP_SRCDIR')) {
+         @chdir(getenv('TEST_PHP_SRCDIR'));
+     }
+     define('TEST_PHP_SRCDIR', getcwd());
+     if (!function_exists('proc_open')) {
+         echo <<<NO_PROC_OPEN_ERROR
  
  +-----------------------------------------------------------+
  |                       ! ERROR !                           |
  +-----------------------------------------------------------+
  
  NO_PROC_OPEN_ERROR;
-               exit(1);
-       }
-       // If timezone is not set, use UTC.
-       if (ini_get('date.timezone') == '') {
-               date_default_timezone_set('UTC');
-       }
-       // Delete some security related environment variables
-       putenv('SSH_CLIENT=deleted');
-       putenv('SSH_AUTH_SOCK=deleted');
-       putenv('SSH_TTY=deleted');
-       putenv('SSH_CONNECTION=deleted');
-       set_time_limit(0);
-       ini_set('pcre.backtrack_limit', PHP_INT_MAX);
-       // delete as much output buffers as possible
-       while (@ob_end_clean()) {
-               ;
-       }
-       if (ob_get_level()) {
-               echo "Not all buffers were deleted.\n";
-       }
-       error_reporting(E_ALL);
-       $environment = $_ENV ?? array();
-       // Note: php.ini-development sets variables_order="GPCS" not "EGPCS", in which case $_ENV is NOT populated.
-       //         detect and handle this case, or die or warn
-       if (empty($environment)) {
-               // not documented, but returns array of all environment variables
-               $environment = getenv();
-       }
-       if (empty($environment['TEMP'])) {
-               $environment['TEMP'] = sys_get_temp_dir();
-               if (empty($environment['TEMP'])) {
-                       // for example, OpCache on Windows will fail in this case because child processes (for tests) will not get
-                       // a TEMP variable, so GetTempPath() will fallback to c:\windows, while GetTempPath() will return %TEMP% for parent
-                       // (likely a different path). The parent will initialize the OpCache in that path, and child will fail to reattach to
-                       // the OpCache because it will be using the wrong path.
-                       die("TEMP environment is NOT set");
-               } else {
-                       if (count($environment) == 1) {
-                               // not having other environment variables, only having TEMP, is probably ok, but strange and may make a
-                               // difference in the test pass rate, so warn the user.
-                               echo "WARNING: Only 1 environment variable will be available to tests(TEMP environment variable)" . PHP_EOL;
-                       }
-               }
-       }
-       //
-       if (IS_WINDOWS && empty($environment["SystemRoot"])) {
-               $environment["SystemRoot"] = getenv("SystemRoot");
-       }
-       $php = null;
-       $php_cgi = null;
-       $phpdbg = null;
-       if (getenv('TEST_PHP_EXECUTABLE')) {
-               $php = getenv('TEST_PHP_EXECUTABLE');
-               if ($php == 'auto') {
-                       $php = TEST_PHP_SRCDIR . '/sapi/cli/php';
-                       putenv("TEST_PHP_EXECUTABLE=$php");
-                       if (!getenv('TEST_PHP_CGI_EXECUTABLE')) {
-                               $php_cgi = TEST_PHP_SRCDIR . '/sapi/cgi/php-cgi';
-                               if (file_exists($php_cgi)) {
-                                       putenv("TEST_PHP_CGI_EXECUTABLE=$php_cgi");
-                               } else {
-                                       $php_cgi = null;
-                               }
-                       }
-               }
-               $environment['TEST_PHP_EXECUTABLE'] = $php;
-       }
-       if (getenv('TEST_PHP_CGI_EXECUTABLE')) {
-               $php_cgi = getenv('TEST_PHP_CGI_EXECUTABLE');
-               if ($php_cgi == 'auto') {
-                       $php_cgi = TEST_PHP_SRCDIR . '/sapi/cgi/php-cgi';
-                       putenv("TEST_PHP_CGI_EXECUTABLE=$php_cgi");
-               }
-               $environment['TEST_PHP_CGI_EXECUTABLE'] = $php_cgi;
-       }
-       if (!getenv('TEST_PHPDBG_EXECUTABLE')) {
-               if (IS_WINDOWS && file_exists(dirname($php) . "/phpdbg.exe")) {
-                       $phpdbg = realpath(dirname($php) . "/phpdbg.exe");
-               } elseif (file_exists(dirname($php) . "/../../sapi/phpdbg/phpdbg")) {
-                       $phpdbg = realpath(dirname($php) . "/../../sapi/phpdbg/phpdbg");
-               } elseif (file_exists("./sapi/phpdbg/phpdbg")) {
-                       $phpdbg = realpath("./sapi/phpdbg/phpdbg");
-               } elseif (file_exists(dirname($php) . "/phpdbg")) {
-                       $phpdbg = realpath(dirname($php) . "/phpdbg");
-               } else {
-                       $phpdbg = null;
-               }
-               if ($phpdbg) {
-                       putenv("TEST_PHPDBG_EXECUTABLE=$phpdbg");
-               }
-       }
-       if (getenv('TEST_PHPDBG_EXECUTABLE')) {
-               $phpdbg = getenv('TEST_PHPDBG_EXECUTABLE');
-               if ($phpdbg == 'auto') {
-                       $phpdbg = TEST_PHP_SRCDIR . '/sapi/phpdbg/phpdbg';
-                       putenv("TEST_PHPDBG_EXECUTABLE=$phpdbg");
-               }
-               $environment['TEST_PHPDBG_EXECUTABLE'] = $phpdbg;
-       }
-       if (getenv('TEST_PHP_LOG_FORMAT')) {
-               $log_format = strtoupper(getenv('TEST_PHP_LOG_FORMAT'));
-       } else {
-               $log_format = 'LEODS';
-       }
-       // Check whether a detailed log is wanted.
-       if (getenv('TEST_PHP_DETAILED')) {
-               $DETAILED = getenv('TEST_PHP_DETAILED');
-       } else {
-               $DETAILED = 0;
-       }
-       junit_init();
-       if (getenv('SHOW_ONLY_GROUPS')) {
-               $SHOW_ONLY_GROUPS = explode(",", getenv('SHOW_ONLY_GROUPS'));
-       } else {
-               $SHOW_ONLY_GROUPS = array();
-       }
-       // Check whether user test dirs are requested.
-       if (getenv('TEST_PHP_USER')) {
-               $user_tests = explode(',', getenv('TEST_PHP_USER'));
-       } else {
-               $user_tests = array();
-       }
-       $exts_to_test = array();
-       $ini_overwrites = array(
-               'output_handler=',
-               'open_basedir=',
-               'disable_functions=',
-               'output_buffering=Off',
-               'error_reporting=' . E_ALL,
-               'display_errors=1',
-               'display_startup_errors=1',
-               'log_errors=0',
-               'html_errors=0',
-               'track_errors=0',
-               'report_memleaks=1',
-               'report_zend_debug=0',
-               'docref_root=',
-               'docref_ext=.html',
-               'error_prepend_string=',
-               'error_append_string=',
-               'auto_prepend_file=',
-               'auto_append_file=',
-               'ignore_repeated_errors=0',
-               'precision=14',
-               'memory_limit=128M',
-               'log_errors_max_len=0',
-               'opcache.fast_shutdown=0',
-               'opcache.file_update_protection=0',
-               'opcache.revalidate_freq=0',
-               'zend.assertions=1',
-               'zend.exception_ignore_args=0',
-       );
-       $no_file_cache = '-d opcache.file_cache= -d opcache.file_cache_only=0';
-       define('PHP_QA_EMAIL', 'qa-reports@lists.php.net');
-       define('QA_SUBMISSION_PAGE', 'http://qa.php.net/buildtest-process.php');
-       define('QA_REPORTS_PAGE', 'http://qa.php.net/reports');
-       define('TRAVIS_CI', (bool)getenv('TRAVIS'));
-       // Determine the tests to be run.
-       $test_files = array();
-       $redir_tests = array();
-       $test_results = array();
-       $PHP_FAILED_TESTS = array(
-               'BORKED' => array(),
-               'FAILED' => array(),
-               'WARNED' => array(),
-               'LEAKED' => array(),
-               'XFAILED' => array(),
-               'XLEAKED' => array(),
-               'SLOW' => array()
-       );
-       // If parameters given assume they represent selected tests to run.
-       $result_tests_file = false;
-       $failed_tests_file = false;
-       $pass_option_n = false;
-       $pass_options = '';
-       $output_file = INIT_DIR . '/php_test_results_' . date('Ymd_Hi') . '.txt';
-       $just_save_results = false;
-       $valgrind = null;
-       $html_output = false;
-       $html_file = null;
-       $temp_source = null;
-       $temp_target = null;
-       $temp_urlbase = null;
-       $conf_passed = null;
-       $no_clean = false;
-       $slow_min_ms = INF;
-       $preload = false;
-       $shuffle = false;
-       $workers = null;
-       $cfgtypes = array('show', 'keep');
-       $cfgfiles = array('skip', 'php', 'clean', 'out', 'diff', 'exp', 'mem');
-       $cfg = array();
-       foreach ($cfgtypes as $type) {
-               $cfg[$type] = array();
-               foreach ($cfgfiles as $file) {
-                       $cfg[$type][$file] = false;
-               }
-       }
-       if (!isset($argc, $argv) || !$argc) {
-               $argv = array(__FILE__);
-               $argc = 1;
-       }
-       if (getenv('TEST_PHP_ARGS')) {
-               $argv = array_merge($argv, explode(' ', getenv('TEST_PHP_ARGS')));
-               $argc = count($argv);
-       }
-       for ($i = 1; $i < $argc; $i++) {
-               $is_switch = false;
-               $switch = substr($argv[$i], 1, 1);
-               $repeat = substr($argv[$i], 0, 1) == '-';
-               while ($repeat) {
-                       if (!$is_switch) {
-                               $switch = substr($argv[$i], 1, 1);
-                       }
-                       $is_switch = true;
-                       if ($repeat) {
-                               foreach ($cfgtypes as $type) {
-                                       if (strpos($switch, '--' . $type) === 0) {
-                                               foreach ($cfgfiles as $file) {
-                                                       if ($switch == '--' . $type . '-' . $file) {
-                                                               $cfg[$type][$file] = true;
-                                                               $is_switch = false;
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       if (!$is_switch) {
-                               $is_switch = true;
-                               break;
-                       }
-                       $repeat = false;
-                       switch ($switch) {
-                               case 'j':
-                                       $workers = substr($argv[$i], 2);
-                                       if (!preg_match('/^\d+$/', $workers) || $workers == 0) {
-                                               error("'$workers' is not a valid number of workers, try e.g. -j16 for 16 workers");
-                                       }
-                                       $workers = intval($workers, 10);
-                                       // Don't use parallel testing infrastructure if there is only one worker.
-                                       if ($workers === 1) {
-                                               $workers = null;
-                                       }
-                                       break;
-                               case 'r':
-                               case 'l':
-                                       $test_list = file($argv[++$i]);
-                                       if ($test_list) {
-                                               foreach ($test_list as $test) {
-                                                       $matches = array();
-                                                       if (preg_match('/^#.*\[(.*)\]\:\s+(.*)$/', $test, $matches)) {
-                                                               $redir_tests[] = array($matches[1], $matches[2]);
-                                                       } else {
-                                                               if (strlen($test)) {
-                                                                       $test_files[] = trim($test);
-                                                               }
-                                                       }
-                                               }
-                                       }
-                                       if ($switch != 'l') {
-                                               break;
-                                       }
-                                       $i--;
-                               // break left intentionally
-                               case 'w':
-                                       $failed_tests_file = fopen($argv[++$i], 'w+t');
-                                       break;
-                               case 'a':
-                                       $failed_tests_file = fopen($argv[++$i], 'a+t');
-                                       break;
-                               case 'W':
-                                       $result_tests_file = fopen($argv[++$i], 'w+t');
-                                       break;
-                               case 'c':
-                                       $conf_passed = $argv[++$i];
-                                       break;
-                               case 'd':
-                                       $ini_overwrites[] = $argv[++$i];
-                                       break;
-                               case 'g':
-                                       $SHOW_ONLY_GROUPS = explode(",", $argv[++$i]);
-                                       break;
-                               //case 'h'
-                               case '--keep-all':
-                                       foreach ($cfgfiles as $file) {
-                                               $cfg['keep'][$file] = true;
-                                       }
-                                       break;
-                               //case 'l'
-                               case 'm':
-                               $valgrind = new RuntestsValgrind($environment);
-                                       break;
-                               case 'M':
-                               $valgrind = new RuntestsValgrind($environment, $argv[++$i]);
-                                       break;
-                               case 'n':
-                                       if (!$pass_option_n) {
-                                               $pass_options .= ' -n';
-                                       }
-                                       $pass_option_n = true;
-                                       break;
-                               case 'e':
-                                       $pass_options .= ' -e';
-                                       break;
-                               case '--preload':
-                                       $preload = true;
-                                       break;
-                               case '--no-clean':
-                                       $no_clean = true;
-                                       break;
-                               case 'p':
-                                       $php = $argv[++$i];
-                                       putenv("TEST_PHP_EXECUTABLE=$php");
-                                       $environment['TEST_PHP_EXECUTABLE'] = $php;
-                                       break;
-                               case 'P':
-                                       $php = PHP_BINARY;
-                                       putenv("TEST_PHP_EXECUTABLE=$php");
-                                       $environment['TEST_PHP_EXECUTABLE'] = $php;
-                                       break;
-                               case 'q':
-                                       putenv('NO_INTERACTION=1');
-                                       $environment['NO_INTERACTION'] = 1;
-                                       break;
-                               //case 'r'
-                               case 's':
-                                       $output_file = $argv[++$i];
-                                       $just_save_results = true;
-                                       break;
-                               case '--set-timeout':
-                                       $environment['TEST_TIMEOUT'] = $argv[++$i];
-                                       break;
-                               case '--show-all':
-                                       foreach ($cfgfiles as $file) {
-                                               $cfg['show'][$file] = true;
-                                       }
-                                       break;
-                               case '--show-slow':
-                                       $slow_min_ms = $argv[++$i];
-                                       break;
-                               case '--temp-source':
-                                       $temp_source = $argv[++$i];
-                                       break;
-                               case '--temp-target':
-                                       $temp_target = $argv[++$i];
-                                       if ($temp_urlbase) {
-                                               $temp_urlbase = $temp_target;
-                                       }
-                                       break;
-                               case '--temp-urlbase':
-                                       $temp_urlbase = $argv[++$i];
-                                       break;
-                               case 'v':
-                               case '--verbose':
-                                       $DETAILED = true;
-                                       break;
-                               case 'x':
-                                       $environment['SKIP_SLOW_TESTS'] = 1;
-                                       break;
-                               case '--offline':
-                                       $environment['SKIP_ONLINE_TESTS'] = 1;
-                                       break;
-                               case '--shuffle':
-                                       $shuffle = true;
-                                       break;
-                               case '--asan':
-                                       $environment['USE_ZEND_ALLOC'] = 0;
-                                       $environment['USE_TRACKED_ALLOC'] = 1;
-                                       $environment['SKIP_ASAN'] = 1;
-                                       $environment['SKIP_PERF_SENSITIVE'] = 1;
-                                       $lsanSuppressions = __DIR__ . '/azure/lsan-suppressions.txt';
-                                       if (file_exists($lsanSuppressions)) {
-                                               $environment['LSAN_OPTIONS'] = 'suppressions=' . $lsanSuppressions
-                                                       . ':print_suppressions=0';
-                                       }
-                                       break;
-                               //case 'w'
-                               case '-':
-                                       // repeat check with full switch
-                                       $switch = $argv[$i];
-                                       if ($switch != '-') {
-                                               $repeat = true;
-                                       }
-                                       break;
-                               case '--html':
-                                       $html_file = fopen($argv[++$i], 'wt');
-                                       $html_output = is_resource($html_file);
-                                       break;
-                               case '--version':
-                                       echo '$Id$' . "\n";
-                                       exit(1);
-                               default:
-                                       echo "Illegal switch '$switch' specified!\n";
-                               case 'h':
-                               case '-help':
-                               case '--help':
-                                       echo <<<HELP
+         exit(1);
+     }
+     // If timezone is not set, use UTC.
+     if (ini_get('date.timezone') == '') {
+         date_default_timezone_set('UTC');
+     }
+     // Delete some security related environment variables
+     putenv('SSH_CLIENT=deleted');
+     putenv('SSH_AUTH_SOCK=deleted');
+     putenv('SSH_TTY=deleted');
+     putenv('SSH_CONNECTION=deleted');
+     set_time_limit(0);
+     ini_set('pcre.backtrack_limit', PHP_INT_MAX);
+     // delete as much output buffers as possible
+     while (@ob_end_clean()) {
+         ;
+     }
+     if (ob_get_level()) {
+         echo "Not all buffers were deleted.\n";
+     }
+     error_reporting(E_ALL);
+     $environment = $_ENV ?? array();
+     // Note: php.ini-development sets variables_order="GPCS" not "EGPCS", in which case $_ENV is NOT populated.
+     //           detect and handle this case, or die or warn
+     if (empty($environment)) {
+         // not documented, but returns array of all environment variables
+         $environment = getenv();
+     }
+     if (empty($environment['TEMP'])) {
+         $environment['TEMP'] = sys_get_temp_dir();
+         if (empty($environment['TEMP'])) {
+             // for example, OpCache on Windows will fail in this case because child processes (for tests) will not get
+             // a TEMP variable, so GetTempPath() will fallback to c:\windows, while GetTempPath() will return %TEMP% for parent
+             // (likely a different path). The parent will initialize the OpCache in that path, and child will fail to reattach to
+             // the OpCache because it will be using the wrong path.
+             die("TEMP environment is NOT set");
+         } else {
+             if (count($environment) == 1) {
+                 // not having other environment variables, only having TEMP, is probably ok, but strange and may make a
+                 // difference in the test pass rate, so warn the user.
+                 echo "WARNING: Only 1 environment variable will be available to tests(TEMP environment variable)" . PHP_EOL;
+             }
+         }
+     }
+     //
 -    if ((substr(PHP_OS, 0, 3) == "WIN") && empty($environment["SystemRoot"])) {
++    if (IS_WINDOWS && empty($environment["SystemRoot"])) {
+         $environment["SystemRoot"] = getenv("SystemRoot");
+     }
+     $php = null;
+     $php_cgi = null;
+     $phpdbg = null;
+     if (getenv('TEST_PHP_EXECUTABLE')) {
+         $php = getenv('TEST_PHP_EXECUTABLE');
+         if ($php == 'auto') {
+             $php = TEST_PHP_SRCDIR . '/sapi/cli/php';
+             putenv("TEST_PHP_EXECUTABLE=$php");
+             if (!getenv('TEST_PHP_CGI_EXECUTABLE')) {
+                 $php_cgi = TEST_PHP_SRCDIR . '/sapi/cgi/php-cgi';
+                 if (file_exists($php_cgi)) {
+                     putenv("TEST_PHP_CGI_EXECUTABLE=$php_cgi");
+                 } else {
+                     $php_cgi = null;
+                 }
+             }
+         }
+         $environment['TEST_PHP_EXECUTABLE'] = $php;
+     }
+     if (getenv('TEST_PHP_CGI_EXECUTABLE')) {
+         $php_cgi = getenv('TEST_PHP_CGI_EXECUTABLE');
+         if ($php_cgi == 'auto') {
+             $php_cgi = TEST_PHP_SRCDIR . '/sapi/cgi/php-cgi';
+             putenv("TEST_PHP_CGI_EXECUTABLE=$php_cgi");
+         }
+         $environment['TEST_PHP_CGI_EXECUTABLE'] = $php_cgi;
+     }
+     if (!getenv('TEST_PHPDBG_EXECUTABLE')) {
 -        if (!strncasecmp(PHP_OS, "win", 3) && file_exists(dirname($php) . "/phpdbg.exe")) {
++        if (IS_WINDOWS && file_exists(dirname($php) . "/phpdbg.exe")) {
+             $phpdbg = realpath(dirname($php) . "/phpdbg.exe");
+         } elseif (file_exists(dirname($php) . "/../../sapi/phpdbg/phpdbg")) {
+             $phpdbg = realpath(dirname($php) . "/../../sapi/phpdbg/phpdbg");
+         } elseif (file_exists("./sapi/phpdbg/phpdbg")) {
+             $phpdbg = realpath("./sapi/phpdbg/phpdbg");
+         } elseif (file_exists(dirname($php) . "/phpdbg")) {
+             $phpdbg = realpath(dirname($php) . "/phpdbg");
+         } else {
+             $phpdbg = null;
+         }
+         if ($phpdbg) {
+             putenv("TEST_PHPDBG_EXECUTABLE=$phpdbg");
+         }
+     }
+     if (getenv('TEST_PHPDBG_EXECUTABLE')) {
+         $phpdbg = getenv('TEST_PHPDBG_EXECUTABLE');
+         if ($phpdbg == 'auto') {
+             $phpdbg = TEST_PHP_SRCDIR . '/sapi/phpdbg/phpdbg';
+             putenv("TEST_PHPDBG_EXECUTABLE=$phpdbg");
+         }
+         $environment['TEST_PHPDBG_EXECUTABLE'] = $phpdbg;
+     }
+     if (getenv('TEST_PHP_LOG_FORMAT')) {
+         $log_format = strtoupper(getenv('TEST_PHP_LOG_FORMAT'));
+     } else {
+         $log_format = 'LEODS';
+     }
+     // Check whether a detailed log is wanted.
+     if (getenv('TEST_PHP_DETAILED')) {
+         $DETAILED = getenv('TEST_PHP_DETAILED');
+     } else {
+         $DETAILED = 0;
+     }
+     junit_init();
+     if (getenv('SHOW_ONLY_GROUPS')) {
+         $SHOW_ONLY_GROUPS = explode(",", getenv('SHOW_ONLY_GROUPS'));
+     } else {
+         $SHOW_ONLY_GROUPS = array();
+     }
+     // Check whether user test dirs are requested.
+     if (getenv('TEST_PHP_USER')) {
+         $user_tests = explode(',', getenv('TEST_PHP_USER'));
+     } else {
+         $user_tests = array();
+     }
+     $exts_to_test = array();
+     $ini_overwrites = array(
+         'output_handler=',
+         'open_basedir=',
+         'disable_functions=',
+         'output_buffering=Off',
+         'error_reporting=' . E_ALL,
+         'display_errors=1',
+         'display_startup_errors=1',
+         'log_errors=0',
+         'html_errors=0',
+         'track_errors=0',
+         'report_memleaks=1',
+         'report_zend_debug=0',
+         'docref_root=',
+         'docref_ext=.html',
+         'error_prepend_string=',
+         'error_append_string=',
+         'auto_prepend_file=',
+         'auto_append_file=',
+         'ignore_repeated_errors=0',
+         'precision=14',
+         'memory_limit=128M',
+         'log_errors_max_len=0',
+         'opcache.fast_shutdown=0',
+         'opcache.file_update_protection=0',
+         'opcache.revalidate_freq=0',
+         'zend.assertions=1',
+         'zend.exception_ignore_args=0',
+     );
+     $no_file_cache = '-d opcache.file_cache= -d opcache.file_cache_only=0';
+     define('PHP_QA_EMAIL', 'qa-reports@lists.php.net');
+     define('QA_SUBMISSION_PAGE', 'http://qa.php.net/buildtest-process.php');
+     define('QA_REPORTS_PAGE', 'http://qa.php.net/reports');
+     define('TRAVIS_CI', (bool)getenv('TRAVIS'));
+     // Determine the tests to be run.
+     $test_files = array();
+     $redir_tests = array();
+     $test_results = array();
+     $PHP_FAILED_TESTS = array(
+         'BORKED' => array(),
+         'FAILED' => array(),
+         'WARNED' => array(),
+         'LEAKED' => array(),
+         'XFAILED' => array(),
+         'XLEAKED' => array(),
+         'SLOW' => array()
+     );
+     // If parameters given assume they represent selected tests to run.
+     $result_tests_file = false;
+     $failed_tests_file = false;
+     $pass_option_n = false;
+     $pass_options = '';
+     $output_file = INIT_DIR . '/php_test_results_' . date('Ymd_Hi') . '.txt';
+     $just_save_results = false;
+     $valgrind = null;
+     $html_output = false;
+     $html_file = null;
+     $temp_source = null;
+     $temp_target = null;
+     $temp_urlbase = null;
+     $conf_passed = null;
+     $no_clean = false;
+     $slow_min_ms = INF;
+     $preload = false;
+     $shuffle = false;
+     $workers = null;
+     $cfgtypes = array('show', 'keep');
+     $cfgfiles = array('skip', 'php', 'clean', 'out', 'diff', 'exp', 'mem');
+     $cfg = array();
+     foreach ($cfgtypes as $type) {
+         $cfg[$type] = array();
+         foreach ($cfgfiles as $file) {
+             $cfg[$type][$file] = false;
+         }
+     }
+     if (!isset($argc, $argv) || !$argc) {
+         $argv = array(__FILE__);
+         $argc = 1;
+     }
+     if (getenv('TEST_PHP_ARGS')) {
+         $argv = array_merge($argv, explode(' ', getenv('TEST_PHP_ARGS')));
+         $argc = count($argv);
+     }
+     for ($i = 1; $i < $argc; $i++) {
+         $is_switch = false;
+         $switch = substr($argv[$i], 1, 1);
+         $repeat = substr($argv[$i], 0, 1) == '-';
+         while ($repeat) {
+             if (!$is_switch) {
+                 $switch = substr($argv[$i], 1, 1);
+             }
+             $is_switch = true;
+             if ($repeat) {
+                 foreach ($cfgtypes as $type) {
+                     if (strpos($switch, '--' . $type) === 0) {
+                         foreach ($cfgfiles as $file) {
+                             if ($switch == '--' . $type . '-' . $file) {
+                                 $cfg[$type][$file] = true;
+                                 $is_switch = false;
+                                 break;
+                             }
+                         }
+                     }
+                 }
+             }
+             if (!$is_switch) {
+                 $is_switch = true;
+                 break;
+             }
+             $repeat = false;
+             switch ($switch) {
+                 case 'j':
+                     $workers = substr($argv[$i], 2);
+                     if (!preg_match('/^\d+$/', $workers) || $workers == 0) {
+                         error("'$workers' is not a valid number of workers, try e.g. -j16 for 16 workers");
+                     }
+                     $workers = intval($workers, 10);
+                     // Don't use parallel testing infrastructure if there is only one worker.
+                     if ($workers === 1) {
+                         $workers = null;
+                     }
+                     break;
+                 case 'r':
+                 case 'l':
+                     $test_list = file($argv[++$i]);
+                     if ($test_list) {
+                         foreach ($test_list as $test) {
+                             $matches = array();
+                             if (preg_match('/^#.*\[(.*)\]\:\s+(.*)$/', $test, $matches)) {
+                                 $redir_tests[] = array($matches[1], $matches[2]);
+                             } else {
+                                 if (strlen($test)) {
+                                     $test_files[] = trim($test);
+                                 }
+                             }
+                         }
+                     }
+                     if ($switch != 'l') {
+                         break;
+                     }
+                     $i--;
+                 // break left intentionally
+                 case 'w':
+                     $failed_tests_file = fopen($argv[++$i], 'w+t');
+                     break;
+                 case 'a':
+                     $failed_tests_file = fopen($argv[++$i], 'a+t');
+                     break;
+                 case 'W':
+                     $result_tests_file = fopen($argv[++$i], 'w+t');
+                     break;
+                 case 'c':
+                     $conf_passed = $argv[++$i];
+                     break;
+                 case 'd':
+                     $ini_overwrites[] = $argv[++$i];
+                     break;
+                 case 'g':
+                     $SHOW_ONLY_GROUPS = explode(",", $argv[++$i]);
+                     break;
+                 //case 'h'
+                 case '--keep-all':
+                     foreach ($cfgfiles as $file) {
+                         $cfg['keep'][$file] = true;
+                     }
+                     break;
+                 //case 'l'
+                 case 'm':
+                 $valgrind = new RuntestsValgrind($environment);
+                     break;
+                 case 'M':
+                 $valgrind = new RuntestsValgrind($environment, $argv[++$i]);
+                     break;
+                 case 'n':
+                     if (!$pass_option_n) {
+                         $pass_options .= ' -n';
+                     }
+                     $pass_option_n = true;
+                     break;
+                 case 'e':
+                     $pass_options .= ' -e';
+                     break;
+                 case '--preload':
+                     $preload = true;
+                     break;
+                 case '--no-clean':
+                     $no_clean = true;
+                     break;
+                 case 'p':
+                     $php = $argv[++$i];
+                     putenv("TEST_PHP_EXECUTABLE=$php");
+                     $environment['TEST_PHP_EXECUTABLE'] = $php;
+                     break;
+                 case 'P':
+                     $php = PHP_BINARY;
+                     putenv("TEST_PHP_EXECUTABLE=$php");
+                     $environment['TEST_PHP_EXECUTABLE'] = $php;
+                     break;
+                 case 'q':
+                     putenv('NO_INTERACTION=1');
+                     $environment['NO_INTERACTION'] = 1;
+                     break;
+                 //case 'r'
+                 case 's':
+                     $output_file = $argv[++$i];
+                     $just_save_results = true;
+                     break;
+                 case '--set-timeout':
+                     $environment['TEST_TIMEOUT'] = $argv[++$i];
+                     break;
+                 case '--show-all':
+                     foreach ($cfgfiles as $file) {
+                         $cfg['show'][$file] = true;
+                     }
+                     break;
+                 case '--show-slow':
+                     $slow_min_ms = $argv[++$i];
+                     break;
+                 case '--temp-source':
+                     $temp_source = $argv[++$i];
+                     break;
+                 case '--temp-target':
+                     $temp_target = $argv[++$i];
+                     if ($temp_urlbase) {
+                         $temp_urlbase = $temp_target;
+                     }
+                     break;
+                 case '--temp-urlbase':
+                     $temp_urlbase = $argv[++$i];
+                     break;
+                 case 'v':
+                 case '--verbose':
+                     $DETAILED = true;
+                     break;
+                 case 'x':
+                     $environment['SKIP_SLOW_TESTS'] = 1;
+                     break;
+                 case '--offline':
+                     $environment['SKIP_ONLINE_TESTS'] = 1;
+                     break;
+                 case '--shuffle':
+                     $shuffle = true;
+                     break;
+                 case '--asan':
+                     $environment['USE_ZEND_ALLOC'] = 0;
+                     $environment['USE_TRACKED_ALLOC'] = 1;
+                     $environment['SKIP_ASAN'] = 1;
+                     $environment['SKIP_PERF_SENSITIVE'] = 1;
+                     $lsanSuppressions = __DIR__ . '/azure/lsan-suppressions.txt';
+                     if (file_exists($lsanSuppressions)) {
+                         $environment['LSAN_OPTIONS'] = 'suppressions=' . $lsanSuppressions
+                             . ':print_suppressions=0';
+                     }
+                     break;
+                 //case 'w'
+                 case '-':
+                     // repeat check with full switch
+                     $switch = $argv[$i];
+                     if ($switch != '-') {
+                         $repeat = true;
+                     }
+                     break;
+                 case '--html':
+                     $html_file = fopen($argv[++$i], 'wt');
+                     $html_output = is_resource($html_file);
+                     break;
+                 case '--version':
+                     echo '$Id$' . "\n";
+                     exit(1);
+                 default:
+                     echo "Illegal switch '$switch' specified!\n";
+                 case 'h':
+                 case '-help':
+                 case '--help':
+                     echo <<<HELP
  Synopsis:
      php run-tests.php [options] [files] [directories]
  
@@@ -615,192 -615,192 +615,192 @@@ Options
      --no-clean  Do not execute clean section if any.
  
  HELP;
-                                       exit(1);
-                       }
-               }
-               if (!$is_switch) {
-                       $testfile = realpath($argv[$i]);
-                       if (!$testfile && strpos($argv[$i], '*') !== false && function_exists('glob')) {
-                               if (substr($argv[$i], -5) == '.phpt') {
-                                       $pattern_match = glob($argv[$i]);
-                               } else {
-                                       if (preg_match("/\*$/", $argv[$i])) {
-                                               $pattern_match = glob($argv[$i] . '.phpt');
-                                       } else {
-                                               die('Cannot find test file "' . $argv[$i] . '".' . PHP_EOL);
-                                       }
-                               }
-                               if (is_array($pattern_match)) {
-                                       $test_files = array_merge($test_files, $pattern_match);
-                               }
-                       } else {
-                               if (is_dir($testfile)) {
-                                       find_files($testfile);
-                               } else {
-                                       if (substr($testfile, -5) == '.phpt') {
-                                               $test_files[] = $testfile;
-                                       } else {
-                                               die('Cannot find test file "' . $argv[$i] . '".' . PHP_EOL);
-                                       }
-                               }
-                       }
-               }
-       }
-       // Default to PHP_BINARY as executable
-       if (!isset($environment['TEST_PHP_EXECUTABLE'])) {
-               $php = PHP_BINARY;
-               putenv("TEST_PHP_EXECUTABLE=$php");
-               $environment['TEST_PHP_EXECUTABLE'] = $php;
-       }
-       if (strlen($conf_passed)) {
-               if (IS_WINDOWS) {
-                       $pass_options .= " -c " . escapeshellarg($conf_passed);
-               } else {
-                       $pass_options .= " -c '" . realpath($conf_passed) . "'";
-               }
-       }
-       $test_files = array_unique($test_files);
-       $test_files = array_merge($test_files, $redir_tests);
-       // Run selected tests.
-       $test_cnt = count($test_files);
-       if ($test_cnt) {
-               putenv('NO_INTERACTION=1');
-               verify_config();
-               write_information();
-               usort($test_files, "test_sort");
-               $start_time = time();
-               if (!$html_output) {
-                       echo "Running selected tests.\n";
-               } else {
-                       show_start($start_time);
-               }
-               $test_idx = 0;
-               run_all_tests($test_files, $environment);
-               $end_time = time();
-               if ($html_output) {
-                       show_end($end_time);
-               }
-               if ($failed_tests_file) {
-                       fclose($failed_tests_file);
-               }
-               if ($result_tests_file) {
-                       fclose($result_tests_file);
-               }
-               compute_summary();
-               if ($html_output) {
-                       fwrite($html_file, "<hr/>\n" . get_summary(false, true));
-               }
-               echo "=====================================================================";
-               echo get_summary(false, false);
-               if ($html_output) {
-                       fclose($html_file);
-               }
-               if ($output_file != '' && $just_save_results) {
-                       save_or_mail_results();
-               }
-               junit_save_xml();
-               if (getenv('REPORT_EXIT_STATUS') !== '0' &&
-                       getenv('REPORT_EXIT_STATUS') !== 'no' && ($sum_results['FAILED'] || $sum_results['BORKED'] || $sum_results['LEAKED'])) {
-                       exit(1);
-               }
-               return;
-       }
-       verify_config();
-       write_information();
-       // Compile a list of all test files (*.phpt).
-       $test_files = array();
-       $exts_tested = count($exts_to_test);
-       $exts_skipped = 0;
-       $ignored_by_ext = 0;
-       sort($exts_to_test);
-       $test_dirs = array();
-       $optionals = array('Zend', 'tests', 'ext', 'sapi');
-       foreach ($optionals as $dir) {
-               if (is_dir($dir)) {
-                       $test_dirs[] = $dir;
-               }
-       }
-       // Convert extension names to lowercase
-       foreach ($exts_to_test as $key => $val) {
-               $exts_to_test[$key] = strtolower($val);
-       }
-       foreach ($test_dirs as $dir) {
-               find_files(TEST_PHP_SRCDIR . "/{$dir}", $dir == 'ext');
-       }
-       foreach ($user_tests as $dir) {
-               find_files($dir, $dir == 'ext');
-       }
-       $test_files = array_unique($test_files);
-       usort($test_files, "test_sort");
-       $start_time = time();
-       show_start($start_time);
-       $test_cnt = count($test_files);
-       $test_idx = 0;
-       run_all_tests($test_files, $environment);
-       $end_time = time();
-       if ($failed_tests_file) {
-               fclose($failed_tests_file);
-       }
-       if ($result_tests_file) {
-               fclose($result_tests_file);
-       }
-       // Summarize results
-       if (0 == count($test_results)) {
-               echo "No tests were run.\n";
-               return;
-       }
-       compute_summary();
-       show_end($end_time);
-       show_summary();
-       if ($html_output) {
-               fclose($html_file);
-       }
-       save_or_mail_results();
-       junit_save_xml();
-       if (getenv('REPORT_EXIT_STATUS') !== '0' &&
-               getenv('REPORT_EXIT_STATUS') !== 'no' && ($sum_results['FAILED'] || $sum_results['LEAKED'])) {
-               exit(1);
-       }
-       exit(0);
+                     exit(1);
+             }
+         }
+         if (!$is_switch) {
+             $testfile = realpath($argv[$i]);
+             if (!$testfile && strpos($argv[$i], '*') !== false && function_exists('glob')) {
+                 if (substr($argv[$i], -5) == '.phpt') {
+                     $pattern_match = glob($argv[$i]);
+                 } else {
+                     if (preg_match("/\*$/", $argv[$i])) {
+                         $pattern_match = glob($argv[$i] . '.phpt');
+                     } else {
+                         die('Cannot find test file "' . $argv[$i] . '".' . PHP_EOL);
+                     }
+                 }
+                 if (is_array($pattern_match)) {
+                     $test_files = array_merge($test_files, $pattern_match);
+                 }
+             } else {
+                 if (is_dir($testfile)) {
+                     find_files($testfile);
+                 } else {
+                     if (substr($testfile, -5) == '.phpt') {
+                         $test_files[] = $testfile;
+                     } else {
+                         die('Cannot find test file "' . $argv[$i] . '".' . PHP_EOL);
+                     }
+                 }
+             }
+         }
+     }
+     // Default to PHP_BINARY as executable
+     if (!isset($environment['TEST_PHP_EXECUTABLE'])) {
+         $php = PHP_BINARY;
+         putenv("TEST_PHP_EXECUTABLE=$php");
+         $environment['TEST_PHP_EXECUTABLE'] = $php;
+     }
+     if (strlen($conf_passed)) {
 -        if (substr(PHP_OS, 0, 3) == "WIN") {
++        if (IS_WINDOWS) {
+             $pass_options .= " -c " . escapeshellarg($conf_passed);
+         } else {
+             $pass_options .= " -c '" . realpath($conf_passed) . "'";
+         }
+     }
+     $test_files = array_unique($test_files);
+     $test_files = array_merge($test_files, $redir_tests);
+     // Run selected tests.
+     $test_cnt = count($test_files);
+     if ($test_cnt) {
+         putenv('NO_INTERACTION=1');
+         verify_config();
+         write_information();
+         usort($test_files, "test_sort");
+         $start_time = time();
+         if (!$html_output) {
+             echo "Running selected tests.\n";
+         } else {
+             show_start($start_time);
+         }
+         $test_idx = 0;
+         run_all_tests($test_files, $environment);
+         $end_time = time();
+         if ($html_output) {
+             show_end($end_time);
+         }
+         if ($failed_tests_file) {
+             fclose($failed_tests_file);
+         }
+         if ($result_tests_file) {
+             fclose($result_tests_file);
+         }
+         compute_summary();
+         if ($html_output) {
+             fwrite($html_file, "<hr/>\n" . get_summary(false, true));
+         }
+         echo "=====================================================================";
+         echo get_summary(false, false);
+         if ($html_output) {
+             fclose($html_file);
+         }
+         if ($output_file != '' && $just_save_results) {
+             save_or_mail_results();
+         }
+         junit_save_xml();
+         if (getenv('REPORT_EXIT_STATUS') !== '0' &&
+             getenv('REPORT_EXIT_STATUS') !== 'no' && ($sum_results['FAILED'] || $sum_results['BORKED'] || $sum_results['LEAKED'])) {
+             exit(1);
+         }
+         return;
+     }
+     verify_config();
+     write_information();
+     // Compile a list of all test files (*.phpt).
+     $test_files = array();
+     $exts_tested = count($exts_to_test);
+     $exts_skipped = 0;
+     $ignored_by_ext = 0;
+     sort($exts_to_test);
+     $test_dirs = array();
+     $optionals = array('Zend', 'tests', 'ext', 'sapi');
+     foreach ($optionals as $dir) {
+         if (is_dir($dir)) {
+             $test_dirs[] = $dir;
+         }
+     }
+     // Convert extension names to lowercase
+     foreach ($exts_to_test as $key => $val) {
+         $exts_to_test[$key] = strtolower($val);
+     }
+     foreach ($test_dirs as $dir) {
+         find_files(TEST_PHP_SRCDIR . "/{$dir}", $dir == 'ext');
+     }
+     foreach ($user_tests as $dir) {
+         find_files($dir, $dir == 'ext');
+     }
+     $test_files = array_unique($test_files);
+     usort($test_files, "test_sort");
+     $start_time = time();
+     show_start($start_time);
+     $test_cnt = count($test_files);
+     $test_idx = 0;
+     run_all_tests($test_files, $environment);
+     $end_time = time();
+     if ($failed_tests_file) {
+         fclose($failed_tests_file);
+     }
+     if ($result_tests_file) {
+         fclose($result_tests_file);
+     }
+     // Summarize results
+     if (0 == count($test_results)) {
+         echo "No tests were run.\n";
+         return;
+     }
+     compute_summary();
+     show_end($end_time);
+     show_summary();
+     if ($html_output) {
+         fclose($html_file);
+     }
+     save_or_mail_results();
+     junit_save_xml();
+     if (getenv('REPORT_EXIT_STATUS') !== '0' &&
+         getenv('REPORT_EXIT_STATUS') !== 'no' && ($sum_results['FAILED'] || $sum_results['LEAKED'])) {
+         exit(1);
+     }
+     exit(0);
  }
  
  if (!function_exists("hrtime")) {
@@@ -913,132 -913,132 +913,132 @@@ VALGRIND    : " . ($valgrind ? $valgrin
  
  function save_or_mail_results()
  {
-       global $sum_results, $just_save_results, $failed_test_summary,
-                  $PHP_FAILED_TESTS, $php, $output_file;
-       /* We got failed Tests, offer the user to send an e-mail to QA team, unless NO_INTERACTION is set */
-       if (!getenv('NO_INTERACTION') && !TRAVIS_CI) {
-               $fp = fopen("php://stdin", "r+");
-               if ($sum_results['FAILED'] || $sum_results['BORKED'] || $sum_results['WARNED'] || $sum_results['LEAKED']) {
-                       echo "\nYou may have found a problem in PHP.";
-               }
-               echo "\nThis report can be automatically sent to the PHP QA team at\n";
-               echo QA_REPORTS_PAGE . " and http://news.php.net/php.qa.reports\n";
-               echo "This gives us a better understanding of PHP's behavior.\n";
-               echo "If you don't want to send the report immediately you can choose\n";
-               echo "option \"s\" to save it.  You can then email it to " . PHP_QA_EMAIL . " later.\n";
-               echo "Do you want to send this report now? [Yns]: ";
-               flush();
-               $user_input = fgets($fp, 10);
-               $just_save_results = (strtolower($user_input[0]) == 's');
-       }
-       if ($just_save_results || !getenv('NO_INTERACTION') || TRAVIS_CI) {
-               if ($just_save_results || TRAVIS_CI || strlen(trim($user_input)) == 0 || strtolower($user_input[0]) == 'y') {
-                       /*
-                        * Collect information about the host system for our report
-                        * Fetch phpinfo() output so that we can see the PHP environment
-                        * Make an archive of all the failed tests
-                        * Send an email
-                        */
-                       if ($just_save_results) {
-                               $user_input = 's';
-                       }
-                       /* Ask the user to provide an email address, so that QA team can contact the user */
-                       if (TRAVIS_CI) {
-                               $user_email = 'travis at php dot net';
-                       } elseif (!strncasecmp($user_input, 'y', 1) || strlen(trim($user_input)) == 0) {
-                               echo "\nPlease enter your email address.\n(Your address will be mangled so that it will not go out on any\nmailinglist in plain text): ";
-                               flush();
-                               $user_email = trim(fgets($fp, 1024));
-                               $user_email = str_replace("@", " at ", str_replace(".", " dot ", $user_email));
-                       }
-                       $failed_tests_data = '';
-                       $sep = "\n" . str_repeat('=', 80) . "\n";
-                       $failed_tests_data .= $failed_test_summary . "\n";
-                       $failed_tests_data .= get_summary(true, false) . "\n";
-                       if ($sum_results['FAILED']) {
-                               foreach ($PHP_FAILED_TESTS['FAILED'] as $test_info) {
-                                       $failed_tests_data .= $sep . $test_info['name'] . $test_info['info'];
-                                       $failed_tests_data .= $sep . file_get_contents(realpath($test_info['output']), FILE_BINARY);
-                                       $failed_tests_data .= $sep . file_get_contents(realpath($test_info['diff']), FILE_BINARY);
-                                       $failed_tests_data .= $sep . "\n\n";
-                               }
-                               $status = "failed";
-                       } else {
-                               $status = "success";
-                       }
-                       $failed_tests_data .= "\n" . $sep . 'BUILD ENVIRONMENT' . $sep;
-                       $failed_tests_data .= "OS:\n" . PHP_OS . " - " . php_uname() . "\n\n";
-                       $ldd = $autoconf = $sys_libtool = $libtool = $compiler = 'N/A';
-                       if (!IS_WINDOWS) {
-                               /* If PHP_AUTOCONF is set, use it; otherwise, use 'autoconf'. */
-                               if (getenv('PHP_AUTOCONF')) {
-                                       $autoconf = shell_exec(getenv('PHP_AUTOCONF') . ' --version');
-                               } else {
-                                       $autoconf = shell_exec('autoconf --version');
-                               }
-                               /* Always use the generated libtool - Mac OSX uses 'glibtool' */
-                               $libtool = shell_exec(INIT_DIR . '/libtool --version');
-                               /* Use shtool to find out if there is glibtool present (MacOSX) */
-                               $sys_libtool_path = shell_exec(__DIR__ . '/build/shtool path glibtool libtool');
-                               if ($sys_libtool_path) {
-                                       $sys_libtool = shell_exec(str_replace("\n", "", $sys_libtool_path) . ' --version');
-                               }
-                               /* Try the most common flags for 'version' */
-                               $flags = array('-v', '-V', '--version');
-                               $cc_status = 0;
-                               foreach ($flags as $flag) {
-                                       system(getenv('CC') . " $flag >/dev/null 2>&1", $cc_status);
-                                       if ($cc_status == 0) {
-                                               $compiler = shell_exec(getenv('CC') . " $flag 2>&1");
-                                               break;
-                                       }
-                               }
-                               $ldd = shell_exec("ldd $php 2>/dev/null");
-                       }
-                       $failed_tests_data .= "Autoconf:\n$autoconf\n";
-                       $failed_tests_data .= "Bundled Libtool:\n$libtool\n";
-                       $failed_tests_data .= "System Libtool:\n$sys_libtool\n";
-                       $failed_tests_data .= "Compiler:\n$compiler\n";
-                       $failed_tests_data .= "Bison:\n" . shell_exec('bison --version 2>/dev/null') . "\n";
-                       $failed_tests_data .= "Libraries:\n$ldd\n";
-                       $failed_tests_data .= "\n";
-                       if (isset($user_email)) {
-                               $failed_tests_data .= "User's E-mail: " . $user_email . "\n\n";
-                       }
-                       $failed_tests_data .= $sep . "PHPINFO" . $sep;
-                       $failed_tests_data .= shell_exec($php . ' -ddisplay_errors=stderr -dhtml_errors=0 -i 2> /dev/null');
-                       if (($just_save_results || !mail_qa_team($failed_tests_data, $status)) && !TRAVIS_CI) {
-                               file_put_contents($output_file, $failed_tests_data);
-                               if (!$just_save_results) {
-                                       echo "\nThe test script was unable to automatically send the report to PHP's QA Team\n";
-                               }
-                               echo "Please send " . $output_file . " to " . PHP_QA_EMAIL . " manually, thank you.\n";
-                       } elseif (!getenv('NO_INTERACTION') && !TRAVIS_CI) {
-                               fwrite($fp, "\nThank you for helping to make PHP better.\n");
-                               fclose($fp);
-                       }
-               }
-       }
+     global $sum_results, $just_save_results, $failed_test_summary,
+            $PHP_FAILED_TESTS, $php, $output_file;
+     /* We got failed Tests, offer the user to send an e-mail to QA team, unless NO_INTERACTION is set */
+     if (!getenv('NO_INTERACTION') && !TRAVIS_CI) {
+         $fp = fopen("php://stdin", "r+");
+         if ($sum_results['FAILED'] || $sum_results['BORKED'] || $sum_results['WARNED'] || $sum_results['LEAKED']) {
+             echo "\nYou may have found a problem in PHP.";
+         }
+         echo "\nThis report can be automatically sent to the PHP QA team at\n";
+         echo QA_REPORTS_PAGE . " and http://news.php.net/php.qa.reports\n";
+         echo "This gives us a better understanding of PHP's behavior.\n";
+         echo "If you don't want to send the report immediately you can choose\n";
+         echo "option \"s\" to save it.        You can then email it to " . PHP_QA_EMAIL . " later.\n";
+         echo "Do you want to send this report now? [Yns]: ";
+         flush();
+         $user_input = fgets($fp, 10);
+         $just_save_results = (strtolower($user_input[0]) == 's');
+     }
+     if ($just_save_results || !getenv('NO_INTERACTION') || TRAVIS_CI) {
+         if ($just_save_results || TRAVIS_CI || strlen(trim($user_input)) == 0 || strtolower($user_input[0]) == 'y') {
+             /*
+              * Collect information about the host system for our report
+              * Fetch phpinfo() output so that we can see the PHP environment
+              * Make an archive of all the failed tests
+              * Send an email
+              */
+             if ($just_save_results) {
+                 $user_input = 's';
+             }
+             /* Ask the user to provide an email address, so that QA team can contact the user */
+             if (TRAVIS_CI) {
+                 $user_email = 'travis at php dot net';
+             } elseif (!strncasecmp($user_input, 'y', 1) || strlen(trim($user_input)) == 0) {
+                 echo "\nPlease enter your email address.\n(Your address will be mangled so that it will not go out on any\nmailinglist in plain text): ";
+                 flush();
+                 $user_email = trim(fgets($fp, 1024));
+                 $user_email = str_replace("@", " at ", str_replace(".", " dot ", $user_email));
+             }
+             $failed_tests_data = '';
+             $sep = "\n" . str_repeat('=', 80) . "\n";
+             $failed_tests_data .= $failed_test_summary . "\n";
+             $failed_tests_data .= get_summary(true, false) . "\n";
+             if ($sum_results['FAILED']) {
+                 foreach ($PHP_FAILED_TESTS['FAILED'] as $test_info) {
+                     $failed_tests_data .= $sep . $test_info['name'] . $test_info['info'];
+                     $failed_tests_data .= $sep . file_get_contents(realpath($test_info['output']), FILE_BINARY);
+                     $failed_tests_data .= $sep . file_get_contents(realpath($test_info['diff']), FILE_BINARY);
+                     $failed_tests_data .= $sep . "\n\n";
+                 }
+                 $status = "failed";
+             } else {
+                 $status = "success";
+             }
+             $failed_tests_data .= "\n" . $sep . 'BUILD ENVIRONMENT' . $sep;
+             $failed_tests_data .= "OS:\n" . PHP_OS . " - " . php_uname() . "\n\n";
+             $ldd = $autoconf = $sys_libtool = $libtool = $compiler = 'N/A';
 -            if (substr(PHP_OS, 0, 3) != "WIN") {
++            if (!IS_WINDOWS) {
+                 /* If PHP_AUTOCONF is set, use it; otherwise, use 'autoconf'. */
+                 if (getenv('PHP_AUTOCONF')) {
+                     $autoconf = shell_exec(getenv('PHP_AUTOCONF') . ' --version');
+                 } else {
+                     $autoconf = shell_exec('autoconf --version');
+                 }
+                 /* Always use the generated libtool - Mac OSX uses 'glibtool' */
+                 $libtool = shell_exec(INIT_DIR . '/libtool --version');
+                 /* Use shtool to find out if there is glibtool present (MacOSX) */
+                 $sys_libtool_path = shell_exec(__DIR__ . '/build/shtool path glibtool libtool');
+                 if ($sys_libtool_path) {
+                     $sys_libtool = shell_exec(str_replace("\n", "", $sys_libtool_path) . ' --version');
+                 }
+                 /* Try the most common flags for 'version' */
+                 $flags = array('-v', '-V', '--version');
+                 $cc_status = 0;
+                 foreach ($flags as $flag) {
+                     system(getenv('CC') . " $flag >/dev/null 2>&1", $cc_status);
+                     if ($cc_status == 0) {
+                         $compiler = shell_exec(getenv('CC') . " $flag 2>&1");
+                         break;
+                     }
+                 }
+                 $ldd = shell_exec("ldd $php 2>/dev/null");
+             }
+             $failed_tests_data .= "Autoconf:\n$autoconf\n";
+             $failed_tests_data .= "Bundled Libtool:\n$libtool\n";
+             $failed_tests_data .= "System Libtool:\n$sys_libtool\n";
+             $failed_tests_data .= "Compiler:\n$compiler\n";
+             $failed_tests_data .= "Bison:\n" . shell_exec('bison --version 2>/dev/null') . "\n";
+             $failed_tests_data .= "Libraries:\n$ldd\n";
+             $failed_tests_data .= "\n";
+             if (isset($user_email)) {
+                 $failed_tests_data .= "User's E-mail: " . $user_email . "\n\n";
+             }
+             $failed_tests_data .= $sep . "PHPINFO" . $sep;
+             $failed_tests_data .= shell_exec($php . ' -ddisplay_errors=stderr -dhtml_errors=0 -i 2> /dev/null');
+             if (($just_save_results || !mail_qa_team($failed_tests_data, $status)) && !TRAVIS_CI) {
+                 file_put_contents($output_file, $failed_tests_data);
+                 if (!$just_save_results) {
+                     echo "\nThe test script was unable to automatically send the report to PHP's QA Team\n";
+                 }
+                 echo "Please send " . $output_file . " to " . PHP_QA_EMAIL . " manually, thank you.\n";
+             } elseif (!getenv('NO_INTERACTION') && !TRAVIS_CI) {
+                 fwrite($fp, "\nThank you for helping to make PHP better.\n");
+                 fclose($fp);
+             }
+         }
+     }
  }
  
  function find_files($dir, $is_ext_dir = false, $ignore = false)
@@@ -1281,1177 -1281,1160 +1281,1177 @@@ function system_with_timeout($commandli
  
  function run_all_tests($test_files, $env, $redir_tested = null)
  {
-       global $test_results, $failed_tests_file, $result_tests_file, $php, $test_idx;
-       // Parallel testing
-       global $PHP_FAILED_TESTS, $workers, $workerID, $workerSock;
-       /* Ignore -jN if there is only one file to analyze. */
-       if ($workers !== null && count($test_files) > 1 && !$workerID) {
-               run_all_tests_parallel($test_files, $env, $redir_tested);
-               return;
-       }
-       foreach ($test_files as $name) {
-               if (is_array($name)) {
-                       $index = "# $name[1]: $name[0]";
-                       if ($redir_tested) {
-                               $name = $name[0];
-                       }
-               } else if ($redir_tested) {
-                       $index = "# $redir_tested: $name";
-               } else {
-                       $index = $name;
-               }
-               $test_idx++;
-               if ($workerID) {
-                       $PHP_FAILED_TESTS = ['BORKED' => [], 'FAILED' => [], 'WARNED' => [], 'LEAKED' => [], 'XFAILED' => [], 'XLEAKED' => [], 'SLOW' => []];
-                       ob_start();
-               }
-               $result = run_test($php, $name, $env);
-               if ($workerID) {
-                       $resultText = ob_get_clean();
-               }
-               if (!is_array($name) && $result != 'REDIR') {
-                       if ($workerID) {
-                               send_message($workerSock, [
-                                       "type" => "test_result",
-                                       "name" => $name,
-                                       "index" => $index,
-                                       "result" => $result,
-                                       "text" => $resultText,
-                                       "PHP_FAILED_TESTS" => $PHP_FAILED_TESTS
-                               ]);
-                               continue;
-                       }
-                       $test_results[$index] = $result;
-                       if ($failed_tests_file && ($result == 'XFAILED' || $result == 'XLEAKED' || $result == 'FAILED' || $result == 'WARNED' || $result == 'LEAKED')) {
-                               fwrite($failed_tests_file, "$index\n");
-                       }
-                       if ($result_tests_file) {
-                               fwrite($result_tests_file, "$result\t$index\n");
-                       }
-               }
-       }
+     global $test_results, $failed_tests_file, $result_tests_file, $php, $test_idx;
+     // Parallel testing
+     global $PHP_FAILED_TESTS, $workers, $workerID, $workerSock;
 -    if ($workers !== null && !$workerID) {
++    /* Ignore -jN if there is only one file to analyze. */
++    if ($workers !== null && count($test_files) > 1 && !$workerID) {
+         run_all_tests_parallel($test_files, $env, $redir_tested);
+         return;
+     }
+     foreach ($test_files as $name) {
+         if (is_array($name)) {
+             $index = "# $name[1]: $name[0]";
+             if ($redir_tested) {
+                 $name = $name[0];
+             }
+         } else if ($redir_tested) {
+             $index = "# $redir_tested: $name";
+         } else {
+             $index = $name;
+         }
+         $test_idx++;
+         if ($workerID) {
+             $PHP_FAILED_TESTS = ['BORKED' => [], 'FAILED' => [], 'WARNED' => [], 'LEAKED' => [], 'XFAILED' => [], 'XLEAKED' => [], 'SLOW' => []];
+             ob_start();
+         }
+         $result = run_test($php, $name, $env);
+         if ($workerID) {
+             $resultText = ob_get_clean();
+         }
+         if (!is_array($name) && $result != 'REDIR') {
+             if ($workerID) {
+                 send_message($workerSock, [
+                     "type" => "test_result",
+                     "name" => $name,
+                     "index" => $index,
+                     "result" => $result,
+                     "text" => $resultText,
+                     "PHP_FAILED_TESTS" => $PHP_FAILED_TESTS
+                 ]);
+                 continue;
+             }
+             $test_results[$index] = $result;
+             if ($failed_tests_file && ($result == 'XFAILED' || $result == 'XLEAKED' || $result == 'FAILED' || $result == 'WARNED' || $result == 'LEAKED')) {
+                 fwrite($failed_tests_file, "$index\n");
+             }
+             if ($result_tests_file) {
+                 fwrite($result_tests_file, "$result\t$index\n");
+             }
+         }
+     }
+ }
+ /** The heart of parallel testing. */
+ function run_all_tests_parallel($test_files, $env, $redir_tested) {
 -    global $workers, $test_idx, $test_cnt, $test_results, $failed_tests_file, $result_tests_file, $PHP_FAILED_TESTS, $shuffle, $SHOW_ONLY_GROUPS;
++    global $workers, $test_idx, $test_cnt, $test_results, $failed_tests_file, $result_tests_file, $PHP_FAILED_TESTS, $shuffle, $SHOW_ONLY_GROUPS, $valgrind;
+     // The PHP binary running run-tests.php, and run-tests.php itself
+     // This PHP executable is *not* necessarily the same as the tested version
+     $thisPHP = PHP_BINARY;
+     $thisScript = __FILE__;
+     $workerProcs = [];
+     $workerSocks = [];
+     echo "=====================================================================\n";
+     echo "========= WELCOME TO THE FUTURE: run-tests PARALLEL EDITION =========\n";
+     echo "=====================================================================\n";
+     // Each test may specify a list of conflict keys. While a test that conflicts with
+     // key K is running, no other test that conflicts with K may run. Conflict keys are
+     // specified either in the --CONFLICTS-- section, or CONFLICTS file inside a directory.
+     $dirConflictsWith = [];
+     $fileConflictsWith = [];
+     $sequentialTests = [];
+     foreach ($test_files as $i => $file) {
+         $contents = file_get_contents($file);
+         if (preg_match('/^--CONFLICTS--(.+?)^--/ms', $contents, $matches)) {
+             $conflicts = parse_conflicts($matches[1]);
+         } else {
+             // Cache per-directory conflicts in a separate map, so we compute these only once.
+             $dir = dirname($file);
+             if (!isset($dirConflictsWith[$dir])) {
+                 $dirConflicts = [];
+                 if (file_exists($dir . '/CONFLICTS')) {
+                     $contents = file_get_contents($dir . '/CONFLICTS');
+                     $dirConflicts = parse_conflicts($contents);
+                 }
+                 $dirConflictsWith[$dir] = $dirConflicts;
+             }
+             $conflicts = $dirConflictsWith[$dir];
+         }
+         // For tests conflicting with "all", no other tests may run in parallel. We'll run these
+         // tests separately at the end, when only one worker is left.
+         if (in_array('all', $conflicts, true)) {
+             $sequentialTests[] = $file;
+             unset($test_files[$i]);
+         }
+         $fileConflictsWith[$file] = $conflicts;
+     }
+     // Some tests assume that they are executed in a certain order. We will be popping from
+     // $test_files, so reverse its order here. This makes sure that order is preserved at least
+     // for tests with a common conflict key.
+     $test_files = array_reverse($test_files);
+     // To discover parallelization issues it is useful to randomize the test order.
+     if ($shuffle) {
+         shuffle($test_files);
+     }
++    /* Don't start more workers than test files */
++    $workers = max(1, min($workers, count($test_files)));
+     echo "Spawning workers… ";
+     // We use sockets rather than STDIN/STDOUT for comms because on Windows,
+     // those can't be non-blocking for some reason.
+     $listenSock = stream_socket_server("tcp://127.0.0.1:0") or error("Couldn't create socket on localhost.");
+     $sockName = stream_socket_get_name($listenSock, false);
+     // PHP is terrible and returns IPv6 addresses not enclosed by []
+     $portPos = strrpos($sockName, ":");
+     $sockHost = substr($sockName, 0, $portPos);
+     if (FALSE !== strpos($sockHost, ":")) {
+         $sockHost = "[$sockHost]";
+     }
+     $sockPort = substr($sockName, $portPos + 1);
+     $sockUri = "tcp://$sockHost:$sockPort";
++    $totalFileCount = count($test_files);
+     for ($i = 1; $i <= $workers; $i++) {
+         $proc = proc_open(
+             $thisPHP . ' ' . escapeshellarg($thisScript),
+             [], // Inherit our stdin, stdout and stderr
+             $pipes,
+             NULL,
+             $_ENV + [
+                 "TEST_PHP_WORKER" => $i,
+                 "TEST_PHP_URI" => $sockUri,
+             ],
+             [
+                 "suppress_errors" => TRUE
+             ]
+         );
+         if ($proc === FALSE) {
+             kill_children($workerProcs);
+             error("Failed to spawn worker $i");
+         }
+         $workerProcs[$i] = $proc;
+         $workerSock = stream_socket_accept($listenSock, 5);
+         if ($workerSock === FALSE) {
+             kill_children($workerProcs);
+             error("Failed to accept connection from worker $i");
+         }
+         $greeting = base64_encode(serialize([
+             "type" => "hello",
+             "workerID" => $i,
+             "GLOBALS" => $GLOBALS,
+             "constants" => [
+                 "INIT_DIR" => INIT_DIR,
+                 "TEST_PHP_SRCDIR" => TEST_PHP_SRCDIR,
+                 "PHP_QA_EMAIL" => PHP_QA_EMAIL,
+                 "QA_SUBMISSION_PAGE" => QA_SUBMISSION_PAGE,
+                 "QA_REPORTS_PAGE" => QA_REPORTS_PAGE,
+                 "TRAVIS_CI" => TRAVIS_CI
+             ]
+         ])) . "\n";
+         stream_set_timeout($workerSock, 5);
+         if (fwrite($workerSock, $greeting) === FALSE) {
+             kill_children($workerProcs);
+             error("Failed to send greeting to worker $i.");
+         }
+         $rawReply = fgets($workerSock);
+         if ($rawReply === FALSE) {
+             kill_children($workerProcs);
+             error("Failed to read greeting reply from worker $i.");
+         }
+         $reply = unserialize(base64_decode($rawReply));
+         if (!$reply || $reply["type"] !== "hello_reply" || $reply["workerID"] !== $i) {
+             kill_children($workerProcs);
+             error("Greeting reply from worker $i unexpected or could not be decoded: '$rawReply'");
+         }
+         stream_set_timeout($workerSock, 0);
+         stream_set_blocking($workerSock, FALSE);
+         $workerSocks[$i] = $workerSock;
+         echo "$i ";
+     }
+     echo "… done!\n";
+     echo "=====================================================================\n";
+     echo "\n";
+     $rawMessageBuffers = [];
+     $testsInProgress = 0;
+     // Map from conflict key to worker ID.
+     $activeConflicts = [];
+     // Tests waiting due to conflicts. Map from conflict key to array.
+     $waitingTests = [];
+ escape:
+     while ($test_files || $sequentialTests || $testsInProgress > 0) {
+         $toRead = array_values($workerSocks);
+         $toWrite = NULL;
+         $toExcept = NULL;
+         if (stream_select($toRead, $toWrite, $toExcept, 10)) {
+             foreach ($toRead as $workerSock) {
+                 $i = array_search($workerSock, $workerSocks);
+                 if ($i === FALSE) {
+                     kill_children($workerProcs);
+                     error("Could not find worker stdout in array of worker stdouts, THIS SHOULD NOT HAPPEN.");
+                 }
+                 while (FALSE !== ($rawMessage = fgets($workerSock))) {
+                     // work around fgets truncating things
+                     if (($rawMessageBuffers[$i] ?? '') !== '') {
+                         $rawMessage = $rawMessageBuffers[$i] . $rawMessage;
+                         $rawMessageBuffers[$i] = '';
+                     }
+                     if (substr($rawMessage, -1) !== "\n") {
+                         $rawMessageBuffers[$i] = $rawMessage;
+                         continue;
+                     }
+                     $message = unserialize(base64_decode($rawMessage));
+                     if (!$message) {
+                         kill_children($workerProcs);
+                         $stuff = fread($workerSock, 65536);
+                         error("Could not decode message from worker $i: '$rawMessage$stuff'");
+                     }
+                     switch ($message["type"]) {
+                         case "tests_finished":
+                             $testsInProgress--;
+                             foreach ($activeConflicts as $key => $workerId) {
+                                 if ($workerId === $i) {
+                                     unset($activeConflicts[$key]);
+                                     if (isset($waitingTests[$key])) {
+                                         while ($test = array_pop($waitingTests[$key])) {
+                                             $test_files[] = $test;
+                                         }
+                                         unset($waitingTests[$key]);
+                                     }
+                                 }
+                             }
+                             if (junit_enabled()) {
+                                 junit_merge_results($message["junit"]);
+                             }
+                             // intentional fall-through
+                         case "ready":
+                             // Schedule sequential tests only once we are down to one worker.
+                             if (count($workerProcs) === 1 && $sequentialTests) {
+                                 $test_files = array_merge($test_files, $sequentialTests);
+                                 $sequentialTests = [];
+                             }
+                             // Batch multiple tests to reduce communication overhead.
++                            // - When valgrind is used, communication overhead is relatively small,
++                            //   so just use a batch size of 1.
++                            // - If this is running a small enough number of tests,
++                            //   reduce the batch size to give batches to more workers.
+                             $files = [];
 -                            $batchSize = $shuffle ? 4 : 32;
++                            $maxBatchSize = $valgrind ? 1 : ($shuffle ? 4 : 32);
++                            $averageFilesPerWorker = max(1, (int)ceil($totalFileCount / count($workerProcs)));
++                            $batchSize = min($maxBatchSize, $averageFilesPerWorker);
+                             while (count($files) <= $batchSize && $file = array_pop($test_files)) {
+                                 foreach ($fileConflictsWith[$file] as $conflictKey) {
+                                     if (isset($activeConflicts[$conflictKey])) {
+                                         $waitingTests[$conflictKey][] = $file;
+                                         continue 2;
+                                     }
+                                 }
+                                 $files[] = $file;
+                             }
+                             if ($files) {
+                                 foreach ($files as $file) {
+                                     foreach ($fileConflictsWith[$file] as $conflictKey) {
+                                         $activeConflicts[$conflictKey] = $i;
+                                     }
+                                 }
+                                 $testsInProgress++;
+                                 send_message($workerSocks[$i], [
+                                     "type" => "run_tests",
+                                     "test_files" => $files,
+                                     "env" => $env,
+                                     "redir_tested" => $redir_tested
+                                 ]);
+                             } else {
+                                 proc_terminate($workerProcs[$i]);
+                                 unset($workerProcs[$i]);
+                                 unset($workerSocks[$i]);
+                                 goto escape;
+                             }
+                             break;
+                         case "test_result":
+                             list($name, $index, $result, $resultText) = [$message["name"], $message["index"], $message["result"], $message["text"]];
+                             foreach ($message["PHP_FAILED_TESTS"] as $category => $tests) {
+                                 $PHP_FAILED_TESTS[$category] = array_merge($PHP_FAILED_TESTS[$category], $tests);
+                             }
+                             $test_idx++;
+                             if (!$SHOW_ONLY_GROUPS) {
+                                 clear_show_test();
+                             }
+                             echo $resultText;
+                             if (!$SHOW_ONLY_GROUPS) {
+                                 show_test($test_idx, count($workerProcs) . "/$workers concurrent test workers running");
+                             }
+                             if (!is_array($name) && $result != 'REDIR') {
+                                 $test_results[$index] = $result;
+                                 if ($failed_tests_file && ($result == 'XFAILED' || $result == 'XLEAKED' || $result == 'FAILED' || $result == 'WARNED' || $result == 'LEAKED')) {
+                                     fwrite($failed_tests_file, "$index\n");
+                                 }
+                                 if ($result_tests_file) {
+                                     fwrite($result_tests_file, "$result\t$index\n");
+                                 }
+                             }
+                             break;
+                         case "error":
+                             kill_children($workerProcs);
+                             error("Worker $i reported error: $message[msg]");
+                             break;
+                         case "php_error":
+                             kill_children($workerProcs);
+                             $error_consts = [
+                                 'E_ERROR',
+                                 'E_WARNING',
+                                 'E_PARSE',
+                                 'E_NOTICE',
+                                 'E_CORE_ERROR',
+                                 'E_CORE_WARNING',
+                                 'E_COMPILE_ERROR',
+                                 'E_COMPILE_WARNING',
+                                 'E_USER_ERROR',
+                                 'E_USER_WARNING',
+                                 'E_USER_NOTICE',
+                                 'E_STRICT', // TODO Cleanup when removed from Zend Engine.
+                                 'E_RECOVERABLE_ERROR',
+                                 'E_USER_DEPRECATED'
+                             ];
+                             $error_consts = array_combine(array_map('constant', $error_consts), $error_consts);
+                             error("Worker $i reported unexpected {$error_consts[$message['errno']]}: $message[errstr] in $message[errfile] on line $message[errline]");
+                         default:
+                             kill_children($workerProcs);
+                             error("Unrecognised message type '$message[type]' from worker $i");
+                     }
+                 }
+             }
+         }
+     }
+     if (!$SHOW_ONLY_GROUPS) {
+         clear_show_test();
+     }
+     kill_children($workerProcs);
+     if ($testsInProgress < 0) {
+         error("$testsInProgress test batches “in progress”, which is less than zero. THIS SHOULD NOT HAPPEN.");
+     }
+ }
+ function send_message($stream, array $message) {
+     $blocking = stream_get_meta_data($stream)["blocked"];
+     stream_set_blocking($stream, true);
+     fwrite($stream, base64_encode(serialize($message)) . "\n");
+     stream_set_blocking($stream, $blocking);
+ }
+ function kill_children(array $children) {
+     foreach ($children as $child) {
+         if ($child) {
+             proc_terminate($child);
+         }
+     }
  }
  
- /** The heart of parallel testing. */
- function run_all_tests_parallel($test_files, $env, $redir_tested) {
-       global $workers, $test_idx, $test_cnt, $test_results, $failed_tests_file, $result_tests_file, $PHP_FAILED_TESTS, $shuffle, $SHOW_ONLY_GROUPS, $valgrind;
-       // The PHP binary running run-tests.php, and run-tests.php itself
-       // This PHP executable is *not* necessarily the same as the tested version
-       $thisPHP = PHP_BINARY;
-       $thisScript = __FILE__;
-       $workerProcs = [];
-       $workerSocks = [];
-       echo "=====================================================================\n";
-       echo "========= WELCOME TO THE FUTURE: run-tests PARALLEL EDITION =========\n";
-       echo "=====================================================================\n";
-       // Each test may specify a list of conflict keys. While a test that conflicts with
-       // key K is running, no other test that conflicts with K may run. Conflict keys are
-       // specified either in the --CONFLICTS-- section, or CONFLICTS file inside a directory.
-       $dirConflictsWith = [];
-       $fileConflictsWith = [];
-       $sequentialTests = [];
-       foreach ($test_files as $i => $file) {
-               $contents = file_get_contents($file);
-               if (preg_match('/^--CONFLICTS--(.+?)^--/ms', $contents, $matches)) {
-                       $conflicts = parse_conflicts($matches[1]);
-               } else {
-                       // Cache per-directory conflicts in a separate map, so we compute these only once.
-                       $dir = dirname($file);
-                       if (!isset($dirConflictsWith[$dir])) {
-                               $dirConflicts = [];
-                               if (file_exists($dir . '/CONFLICTS')) {
-                                       $contents = file_get_contents($dir . '/CONFLICTS');
-                                       $dirConflicts = parse_conflicts($contents);
-                               }
-                               $dirConflictsWith[$dir] = $dirConflicts;
-                       }
-                       $conflicts = $dirConflictsWith[$dir];
-               }
-               // For tests conflicting with "all", no other tests may run in parallel. We'll run these
-               // tests separately at the end, when only one worker is left.
-               if (in_array('all', $conflicts, true)) {
-                       $sequentialTests[] = $file;
-                       unset($test_files[$i]);
-               }
-               $fileConflictsWith[$file] = $conflicts;
-       }
-       // Some tests assume that they are executed in a certain order. We will be popping from
-       // $test_files, so reverse its order here. This makes sure that order is preserved at least
-       // for tests with a common conflict key.
-       $test_files = array_reverse($test_files);
-       // To discover parallelization issues it is useful to randomize the test order.
-       if ($shuffle) {
-               shuffle($test_files);
-       }
-       /* Don't start more workers than test files */
-       $workers = max(1, min($workers, count($test_files)));
-       echo "Spawning workers… ";
-       // We use sockets rather than STDIN/STDOUT for comms because on Windows,
-       // those can't be non-blocking for some reason.
-       $listenSock = stream_socket_server("tcp://127.0.0.1:0") or error("Couldn't create socket on localhost.");
-       $sockName = stream_socket_get_name($listenSock, false);
-       // PHP is terrible and returns IPv6 addresses not enclosed by []
-       $portPos = strrpos($sockName, ":");
-       $sockHost = substr($sockName, 0, $portPos);
-       if (FALSE !== strpos($sockHost, ":")) {
-               $sockHost = "[$sockHost]";
-       }
-       $sockPort = substr($sockName, $portPos + 1);
-       $sockUri = "tcp://$sockHost:$sockPort";
-       $totalFileCount = count($test_files);
-       for ($i = 1; $i <= $workers; $i++) {
-               $proc = proc_open(
-                       $thisPHP . ' ' . escapeshellarg($thisScript),
-                       [], // Inherit our stdin, stdout and stderr
-                       $pipes,
-                       NULL,
-                       $_ENV + [
-                               "TEST_PHP_WORKER" => $i,
-                               "TEST_PHP_URI" => $sockUri,
-                       ],
-                       [
-                               "suppress_errors" => TRUE
-                       ]
-               );
-               if ($proc === FALSE) {
-                       kill_children($workerProcs);
-                       error("Failed to spawn worker $i");
-               }
-               $workerProcs[$i] = $proc;
-               $workerSock = stream_socket_accept($listenSock, 5);
-               if ($workerSock === FALSE) {
-                       kill_children($workerProcs);
-                       error("Failed to accept connection from worker $i");
-               }
-               $greeting = base64_encode(serialize([
-                       "type" => "hello",
-                       "workerID" => $i,
-                       "GLOBALS" => $GLOBALS,
-                       "constants" => [
-                               "INIT_DIR" => INIT_DIR,
-                               "TEST_PHP_SRCDIR" => TEST_PHP_SRCDIR,
-                               "PHP_QA_EMAIL" => PHP_QA_EMAIL,
-                               "QA_SUBMISSION_PAGE" => QA_SUBMISSION_PAGE,
-                               "QA_REPORTS_PAGE" => QA_REPORTS_PAGE,
-                               "TRAVIS_CI" => TRAVIS_CI
-                       ]
-               ])) . "\n";
-               stream_set_timeout($workerSock, 5);
-               if (fwrite($workerSock, $greeting) === FALSE) {
-                       kill_children($workerProcs);
-                       error("Failed to send greeting to worker $i.");
-               }
-               $rawReply = fgets($workerSock);
-               if ($rawReply === FALSE) {
-                       kill_children($workerProcs);
-                       error("Failed to read greeting reply from worker $i.");
-               }
-               $reply = unserialize(base64_decode($rawReply));
-               if (!$reply || $reply["type"] !== "hello_reply" || $reply["workerID"] !== $i) {
-                       kill_children($workerProcs);
-                       error("Greeting reply from worker $i unexpected or could not be decoded: '$rawReply'");
-               }
-               stream_set_timeout($workerSock, 0);
-               stream_set_blocking($workerSock, FALSE);
-               $workerSocks[$i] = $workerSock;
-               echo "$i ";
-       }
-       echo "… done!\n";
-       echo "=====================================================================\n";
-       echo "\n";
-       $rawMessageBuffers = [];
-       $testsInProgress = 0;
-       // Map from conflict key to worker ID.
-       $activeConflicts = [];
-       // Tests waiting due to conflicts. Map from conflict key to array.
-       $waitingTests = [];
+ function run_worker() {
+     global $workerID, $workerSock;
+     $sockUri = getenv("TEST_PHP_URI");
+     $workerSock = stream_socket_client($sockUri, $_, $_, 5) or error("Couldn't connect to $sockUri");
+     $greeting = fgets($workerSock);
+     $greeting = unserialize(base64_decode($greeting)) or die("Could not decode greeting\n");
+     if ($greeting["type"] !== "hello" || $greeting["workerID"] !== $workerID) {
+         error("Unexpected greeting of type $greeting[type] and for worker $greeting[workerID]");
+     }
+     set_error_handler(function ($errno, $errstr, $errfile, $errline) use ($workerSock) {
+         if (error_reporting() & $errno) {
+             send_message($workerSock, compact('errno', 'errstr', 'errfile', 'errline') + [
+                 'type' => 'php_error'
+             ]);
+         }
+         return true;
+     });
+     foreach ($greeting["GLOBALS"] as $var => $value) {
+         if ($var !== "workerID" && $var !== "workerSock" && $var !== "GLOBALS") {
+             $GLOBALS[$var] = $value;
+         }
+     }
+     foreach ($greeting["constants"] as $const => $value) {
+         define($const, $value);
+     }
+     send_message($workerSock, [
+         "type" => "hello_reply",
+         "workerID" => $workerID
+     ]);
+     send_message($workerSock, [
+         "type" => "ready"
+     ]);
+     while (($command = fgets($workerSock))) {
+         $command = unserialize(base64_decode($command));
+         switch ($command["type"]) {
+             case "run_tests":
+                 run_all_tests($command["test_files"], $command["env"], $command["redir_tested"]);
+                 send_message($workerSock, [
+                     "type" => "tests_finished",
+                     "junit" => junit_enabled() ? $GLOBALS['JUNIT'] : null,
+                 ]);
+                 junit_init();
+                 break;
+             default:
+                 send_message($workerSock, [
+                     "type" => "error",
+                     "msg" => "Unrecognised message type: $command[type]"
+                 ]);
+                 break 2;
+         }
+     }
+ }
+ //
+ //  Show file or result block
+ //
+ function show_file_block($file, $block, $section = null)
+ {
+     global $cfg;
+     if ($cfg['show'][$file]) {
+         if (is_null($section)) {
+             $section = strtoupper($file);
+         }
+         echo "\n========" . $section . "========\n";
+         echo rtrim($block);
+         echo "\n========DONE========\n";
+     }
+ }
+ //
+ //  Run an individual test case.
+ //
+ function run_test($php, $file, $env)
+ {
+     global $log_format, $ini_overwrites, $PHP_FAILED_TESTS;
+     global $pass_options, $DETAILED, $IN_REDIRECT, $test_cnt, $test_idx;
+     global $valgrind, $temp_source, $temp_target, $cfg, $environment;
+     global $no_clean;
+     global $SHOW_ONLY_GROUPS;
+     global $no_file_cache;
+     global $slow_min_ms;
+     global $preload;
+     // Parallel testing
+     global $workerID;
+     $temp_filenames = null;
+     $org_file = $file;
+     if (isset($env['TEST_PHP_CGI_EXECUTABLE'])) {
+         $php_cgi = $env['TEST_PHP_CGI_EXECUTABLE'];
+     }
+     if (isset($env['TEST_PHPDBG_EXECUTABLE'])) {
+         $phpdbg = $env['TEST_PHPDBG_EXECUTABLE'];
+     }
+     if (is_array($file)) {
+         $file = $file[0];
+     }
+     if ($DETAILED) echo "
+ =================
+ TEST $file
+ ";
+     // Load the sections of the test file.
+     $section_text = array('TEST' => '');
+     $fp = fopen($file, "rb") or error("Cannot open test file: $file");
+     $bork_info = null;
+     if (!feof($fp)) {
+         $line = fgets($fp);
+         if ($line === false) {
+             $bork_info = "cannot read test";
+         }
+     } else {
+         $bork_info = "empty test [$file]";
+     }
+     if ($bork_info === null && strncmp('--TEST--', $line, 8)) {
+         $bork_info = "tests must start with --TEST-- [$file]";
+     }
+     $section = 'TEST';
+     $secfile = false;
+     $secdone = false;
+     while (!feof($fp)) {
+         $line = fgets($fp);
+         if ($line === false) {
+             break;
+         }
+         // Match the beginning of a section.
+         if (preg_match('/^--([_A-Z]+)--/', $line, $r)) {
+             $section = (string)$r[1];
+             if (isset($section_text[$section]) && $section_text[$section]) {
+                 $bork_info = "duplicated $section section";
+             }
+             // check for unknown sections
+             if (!in_array($section, array(
+                 'EXPECT', 'EXPECTF', 'EXPECTREGEX', 'EXPECTREGEX_EXTERNAL', 'EXPECT_EXTERNAL', 'EXPECTF_EXTERNAL', 'EXPECTHEADERS',
+                 'POST', 'POST_RAW', 'GZIP_POST', 'DEFLATE_POST', 'PUT', 'GET', 'COOKIE', 'ARGS',
+                 'FILE', 'FILEEOF', 'FILE_EXTERNAL', 'REDIRECTTEST',
+                 'CAPTURE_STDIO', 'STDIN', 'CGI', 'PHPDBG',
+                 'INI', 'ENV', 'EXTENSIONS',
+                 'SKIPIF', 'XFAIL', 'XLEAK', 'CLEAN',
+                 'CREDITS', 'DESCRIPTION', 'CONFLICTS', 'WHITESPACE_SENSITIVE',
+             ))) {
+                 $bork_info = 'Unknown section "' . $section . '"';
+             }
+             $section_text[$section] = '';
+             $secfile = $section == 'FILE' || $section == 'FILEEOF' || $section == 'FILE_EXTERNAL';
+             $secdone = false;
+             continue;
+         }
+         // Add to the section text.
+         if (!$secdone) {
+             $section_text[$section] .= $line;
+         }
+         // End of actual test?
+         if ($secfile && preg_match('/^===DONE===\s*$/', $line)) {
+             $secdone = true;
+         }
+     }
+     // the redirect section allows a set of tests to be reused outside of
+     // a given test dir
+     if ($bork_info === null) {
+         if (isset($section_text['REDIRECTTEST'])) {
+             if ($IN_REDIRECT) {
+                 $bork_info = "Can't redirect a test from within a redirected test";
+             }
+         } else {
+             if (!isset($section_text['PHPDBG']) && isset($section_text['FILE']) + isset($section_text['FILEEOF']) + isset($section_text['FILE_EXTERNAL']) != 1) {
+                 $bork_info = "missing section --FILE--";
+             }
+             if (isset($section_text['FILEEOF'])) {
+                 $section_text['FILE'] = preg_replace("/[\r\n]+$/", '', $section_text['FILEEOF']);
+                 unset($section_text['FILEEOF']);
+             }
+             foreach (array('FILE', 'EXPECT', 'EXPECTF', 'EXPECTREGEX') as $prefix) {
+                 $key = $prefix . '_EXTERNAL';
+                 if (isset($section_text[$key])) {
+                     // don't allow tests to retrieve files from anywhere but this subdirectory
+                     $section_text[$key] = dirname($file) . '/' . trim(str_replace('..', '', $section_text[$key]));
+                     if (file_exists($section_text[$key])) {
+                         $section_text[$prefix] = file_get_contents($section_text[$key], FILE_BINARY);
+                         unset($section_text[$key]);
+                     } else {
+                         $bork_info = "could not load --" . $key . "-- " . dirname($file) . '/' . trim($section_text[$key]);
+                     }
+                 }
+             }
+             if ((isset($section_text['EXPECT']) + isset($section_text['EXPECTF']) + isset($section_text['EXPECTREGEX'])) != 1) {
+                 $bork_info = "missing section --EXPECT--, --EXPECTF-- or --EXPECTREGEX--";
+             }
+         }
+     }
+     fclose($fp);
+     $shortname = str_replace(TEST_PHP_SRCDIR . '/', '', $file);
+     $tested_file = $shortname;
+     if ($bork_info !== null) {
+         show_result("BORK", $bork_info, $tested_file);
+         $PHP_FAILED_TESTS['BORKED'][] = array(
+             'name' => $file,
+             'test_name' => '',
+             'output' => '',
+             'diff' => '',
+             'info' => "$bork_info [$file]",
+         );
+         junit_mark_test_as('BORK', $shortname, $tested_file, 0, $bork_info);
+         return 'BORKED';
+     }
+     if (isset($section_text['CAPTURE_STDIO'])) {
+         $captureStdIn = stripos($section_text['CAPTURE_STDIO'], 'STDIN') !== false;
+         $captureStdOut = stripos($section_text['CAPTURE_STDIO'], 'STDOUT') !== false;
+         $captureStdErr = stripos($section_text['CAPTURE_STDIO'], 'STDERR') !== false;
+     } else {
+         $captureStdIn = true;
+         $captureStdOut = true;
+         $captureStdErr = true;
+     }
+     if ($captureStdOut && $captureStdErr) {
+         $cmdRedirect = ' 2>&1';
+     } else {
+         $cmdRedirect = '';
+     }
+     $tested = trim($section_text['TEST']);
+     /* For GET/POST/PUT tests, check if cgi sapi is available and if it is, use it. */
+     if (array_key_exists('CGI', $section_text) || !empty($section_text['GET']) || !empty($section_text['POST']) || !empty($section_text['GZIP_POST']) || !empty($section_text['DEFLATE_POST']) || !empty($section_text['POST_RAW']) || !empty($section_text['PUT']) || !empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) {
+         if (isset($php_cgi)) {
+             $php = $php_cgi . ' -C ';
 -        } else if (!strncasecmp(PHP_OS, "win", 3) && file_exists(dirname($php) . "/php-cgi.exe")) {
++        } else if (IS_WINDOWS && file_exists(dirname($php) . "/php-cgi.exe")) {
+             $php = realpath(dirname($php) . "/php-cgi.exe") . ' -C ';
+         } else {
+             if (file_exists(dirname($php) . "/../../sapi/cgi/php-cgi")) {
+                 $php = realpath(dirname($php) . "/../../sapi/cgi/php-cgi") . ' -C ';
+             } else if (file_exists("./sapi/cgi/php-cgi")) {
+                 $php = realpath("./sapi/cgi/php-cgi") . ' -C ';
+             } else if (file_exists(dirname($php) . "/php-cgi")) {
+                 $php = realpath(dirname($php) . "/php-cgi") . ' -C ';
+             } else {
+                 show_result('SKIP', $tested, $tested_file, "reason: CGI not available");
+                 junit_init_suite(junit_get_suitename_for($shortname));
+                 junit_mark_test_as('SKIP', $shortname, $tested, 0, 'CGI not available');
+                 return 'SKIPPED';
+             }
+         }
+         $uses_cgi = true;
+     }
+     /* For phpdbg tests, check if phpdbg sapi is available and if it is, use it. */
+     $extra_options = '';
+     if (array_key_exists('PHPDBG', $section_text)) {
+         if (!isset($section_text['STDIN'])) {
+             $section_text['STDIN'] = $section_text['PHPDBG'] . "\n";
+         }
+         if (isset($phpdbg)) {
+             $php = $phpdbg . ' -qIb';
+             // Additional phpdbg command line options for sections that need to
+             // be run straight away. For example, EXTENSIONS, SKIPIF, CLEAN.
+             $extra_options = '-rr';
+         } else {
+             show_result('SKIP', $tested, $tested_file, "reason: phpdbg not available");
+             junit_init_suite(junit_get_suitename_for($shortname));
+             junit_mark_test_as('SKIP', $shortname, $tested, 0, 'phpdbg not available');
+             return 'SKIPPED';
+         }
+     }
+     if (!$SHOW_ONLY_GROUPS && !$workerID) {
+         show_test($test_idx, $shortname);
+     }
+     if (is_array($IN_REDIRECT)) {
+         $temp_dir = $test_dir = $IN_REDIRECT['dir'];
+     } else {
+         $temp_dir = $test_dir = realpath(dirname($file));
+     }
+     if ($temp_source && $temp_target) {
+         $temp_dir = str_replace($temp_source, $temp_target, $temp_dir);
+     }
+     $main_file_name = basename($file, 'phpt');
+     $diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'diff';
+     $log_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'log';
+     $exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'exp';
+     $output_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'out';
+     $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'mem';
+     $sh_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'sh';
+     $temp_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'php';
+     $test_file = $test_dir . DIRECTORY_SEPARATOR . $main_file_name . 'php';
+     $temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'skip.php';
+     $test_skipif = $test_dir . DIRECTORY_SEPARATOR . $main_file_name . 'skip.php';
+     $temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'clean.php';
+     $test_clean = $test_dir . DIRECTORY_SEPARATOR . $main_file_name . 'clean.php';
+     $preload_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'preload.php';
+     $tmp_post = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'post';
+     $tmp_relative_file = str_replace(__DIR__ . DIRECTORY_SEPARATOR, '', $test_file) . 't';
+     if ($temp_source && $temp_target) {
+         $temp_skipif .= 's';
+         $temp_file .= 's';
+         $temp_clean .= 's';
+         $copy_file = $temp_dir . DIRECTORY_SEPARATOR . basename(is_array($file) ? $file[1] : $file) . '.phps';
+         if (!is_dir(dirname($copy_file))) {
+             mkdir(dirname($copy_file), 0777, true) or error("Cannot create output directory - " . dirname($copy_file));
+         }
+         if (isset($section_text['FILE'])) {
+             save_text($copy_file, $section_text['FILE']);
+         }
+         $temp_filenames = array(
+             'file' => $copy_file,
+             'diff' => $diff_filename,
+             'log' => $log_filename,
+             'exp' => $exp_filename,
+             'out' => $output_filename,
+             'mem' => $memcheck_filename,
+             'sh' => $sh_filename,
+             'php' => $temp_file,
+             'skip' => $temp_skipif,
+             'clean' => $temp_clean
+         );
+     }
+     if (is_array($IN_REDIRECT)) {
+         $tested = $IN_REDIRECT['prefix'] . ' ' . trim($section_text['TEST']);
+         $tested_file = $tmp_relative_file;
+         $shortname = str_replace(TEST_PHP_SRCDIR . '/', '', $tested_file);
+     }
+     // unlink old test results
+     @unlink($diff_filename);
+     @unlink($log_filename);
+     @unlink($exp_filename);
+     @unlink($output_filename);
+     @unlink($memcheck_filename);
+     @unlink($sh_filename);
+     @unlink($temp_file);
+     @unlink($test_file);
+     @unlink($temp_skipif);
+     @unlink($test_skipif);
+     @unlink($tmp_post);
+     @unlink($temp_clean);
+     @unlink($test_clean);
+     @unlink($preload_filename);
+     // Reset environment from any previous test.
+     $env['REDIRECT_STATUS'] = '';
+     $env['QUERY_STRING'] = '';
+     $env['PATH_TRANSLATED'] = '';
+     $env['SCRIPT_FILENAME'] = '';
+     $env['REQUEST_METHOD'] = '';
+     $env['CONTENT_TYPE'] = '';
+     $env['CONTENT_LENGTH'] = '';
+     $env['TZ'] = '';
+     if (!empty($section_text['ENV'])) {
+         foreach (explode("\n", trim($section_text['ENV'])) as $e) {
+             $e = explode('=', trim($e), 2);
+             if (!empty($e[0]) && isset($e[1])) {
+                 $env[$e[0]] = $e[1];
+             }
+         }
+     }
+     // Default ini settings
+     $ini_settings = $workerID ? array('opcache.cache_id' => "worker$workerID") : array();
+     // Additional required extensions
+     if (array_key_exists('EXTENSIONS', $section_text)) {
+         $ext_params = array();
+         settings2array($ini_overwrites, $ext_params);
+         $ext_params = settings2params($ext_params);
+         $ext_dir = `$php $pass_options $extra_options $ext_params -d display_errors=0 -r "echo ini_get('extension_dir');"`;
+         $extensions = preg_split("/[\n\r]+/", trim($section_text['EXTENSIONS']));
+         $loaded = explode(",", `$php $pass_options $extra_options $ext_params -d display_errors=0 -r "echo implode(',', get_loaded_extensions());"`);
 -        $ext_prefix = substr(PHP_OS, 0, 3) === "WIN" ? "php_" : "";
++        $ext_prefix = IS_WINDOWS ? "php_" : "";
+         foreach ($extensions as $req_ext) {
+             if (!in_array($req_ext, $loaded)) {
+                 if ($req_ext == 'opcache') {
+                     $ini_settings['zend_extension'][] = $ext_dir . DIRECTORY_SEPARATOR . $ext_prefix . $req_ext . '.' . PHP_SHLIB_SUFFIX;
+                 } else {
+                     $ini_settings['extension'][] = $ext_dir . DIRECTORY_SEPARATOR . $ext_prefix . $req_ext . '.' . PHP_SHLIB_SUFFIX;
+                 }
+             }
+         }
+     }
+     // additional ini overwrites
+     //$ini_overwrites[] = 'setting=value';
+     settings2array($ini_overwrites, $ini_settings);
+     $orig_ini_settings = settings2params($ini_settings);
+     // Any special ini settings
+     // these may overwrite the test defaults...
+     if (array_key_exists('INI', $section_text)) {
+         $section_text['INI'] = str_replace('{PWD}', dirname($file), $section_text['INI']);
+         $section_text['INI'] = str_replace('{TMP}', sys_get_temp_dir(), $section_text['INI']);
++        $replacement = IS_WINDOWS ? '"' . PHP_BINARY . ' -r \"while ($in = fgets(STDIN)) echo $in;\" > $1"' : 'tee $1 >/dev/null';
++        $section_text['INI'] = preg_replace('/{MAIL:(\S+)}/', $replacement, $section_text['INI']);
+         settings2array(preg_split("/[\n\r]+/", $section_text['INI']), $ini_settings);
+     }
+     $ini_settings = settings2params($ini_settings);
+     $env['TEST_PHP_EXTRA_ARGS'] = $pass_options . ' ' . $ini_settings;
+     // Check if test should be skipped.
+     $info = '';
+     $warn = false;
+     if (array_key_exists('SKIPIF', $section_text)) {
+         if (trim($section_text['SKIPIF'])) {
+             show_file_block('skip', $section_text['SKIPIF']);
+             save_text($test_skipif, $section_text['SKIPIF'], $temp_skipif);
 -            $extra = substr(PHP_OS, 0, 3) !== "WIN" ?
++            $extra = !IS_WINDOWS ?
+                 "unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;" : "";
+             if ($valgrind) {
+                 $env['USE_ZEND_ALLOC'] = '0';
+                 $env['ZEND_DONT_UNLOAD_MODULES'] = 1;
+             }
+             junit_start_timer($shortname);
 -            $output = system_with_timeout("$extra $php $pass_options $extra_options -q $orig_ini_settings $no_file_cache -d display_errors=0 \"$test_skipif\"", $env);
++            $output = system_with_timeout("$extra $php $pass_options $extra_options -q $orig_ini_settings $no_file_cache -d display_errors=1 -d display_startup_errors=0 \"$test_skipif\"", $env);
++            $output = trim($output);
+             junit_finish_timer($shortname);
+             if (!$cfg['keep']['skip']) {
+                 @unlink($test_skipif);
+             }
 -            if (!strncasecmp('skip', ltrim($output), 4)) {
++            if (!strncasecmp('skip', $output, 4)) {
 -                if (preg_match('/^\s*skip\s*(.+)\s*/i', $output, $m)) {
++                if (preg_match('/^skip\s*(.+)/i', $output, $m)) {
+                     show_result('SKIP', $tested, $tested_file, "reason: $m[1]", $temp_filenames);
+                 } else {
+                     show_result('SKIP', $tested, $tested_file, '', $temp_filenames);
+                 }
+                 if (!$cfg['keep']['skip']) {
+                     @unlink($test_skipif);
+                 }
+                 $message = !empty($m[1]) ? $m[1] : '';
+                 junit_mark_test_as('SKIP', $shortname, $tested, null, $message);
+                 return 'SKIPPED';
+             }
 -            if (!strncasecmp('info', ltrim($output), 4)) {
 -                if (preg_match('/^\s*info\s*(.+)\s*/i', $output, $m)) {
 -                    $info = " (info: $m[1])";
 -                }
 -            }
 -
 -            if (!strncasecmp('warn', ltrim($output), 4)) {
 -                if (preg_match('/^\s*warn\s*(.+)\s*/i', $output, $m)) {
 -                    $warn = true; /* only if there is a reason */
 -                    $info = " (warn: $m[1])";
 -                }
 -            }
 -
 -            if (!strncasecmp('xfail', ltrim($output), 5)) {
++            if (!strncasecmp('info', $output, 4) && preg_match('/^info\s*(.+)/i', $output, $m)) {
++                $info = " (info: $m[1])";
++            } elseif (!strncasecmp('warn', $output, 4) && preg_match('/^warn\s+(.+)/i', $output, $m)) {
++                $warn = true; /* only if there is a reason */
++                $info = " (warn: $m[1])";
++            } elseif (!strncasecmp('xfail', $output, 5)) {
+                 // Pretend we have an XFAIL section
 -                $section_text['XFAIL'] = trim(substr(ltrim($output), 5));
++                $section_text['XFAIL'] = ltrim(substr($output, 5));
++            } elseif ($output !== '') {
++                show_result("BORK", $output, $tested_file, 'reason: invalid output from SKIPIF', $temp_filenames);
++                $PHP_FAILED_TESTS['BORKED'][] = array(
++                    'name' => $file,
++                    'test_name' => '',
++                    'output' => '',
++                    'diff' => '',
++                    'info' => "$output [$file]",
++                );
++
++                junit_mark_test_as('BORK', $shortname, $tested, null, $output);
++                return 'BORKED';
+             }
+         }
+     }
+     if (!extension_loaded("zlib")
+         && (array_key_exists("GZIP_POST", $section_text)
+         || array_key_exists("DEFLATE_POST", $section_text))) {
+         $message = "ext/zlib required";
+         show_result('SKIP', $tested, $tested_file, "reason: $message", $temp_filenames);
+         junit_mark_test_as('SKIP', $shortname, $tested, null, $message);
+         return 'SKIPPED';
+     }
+     if (isset($section_text['REDIRECTTEST'])) {
+         $test_files = array();
+         $IN_REDIRECT = eval($section_text['REDIRECTTEST']);
+         $IN_REDIRECT['via'] = "via [$shortname]\n\t";
+         $IN_REDIRECT['dir'] = realpath(dirname($file));
+         $IN_REDIRECT['prefix'] = trim($section_text['TEST']);
+         if (!empty($IN_REDIRECT['TESTS'])) {
+             if (is_array($org_file)) {
+                 $test_files[] = $org_file[1];
+             } else {
+                 $GLOBALS['test_files'] = $test_files;
+                 find_files($IN_REDIRECT['TESTS']);
+                 foreach ($GLOBALS['test_files'] as $f) {
+                     $test_files[] = array($f, $file);
+                 }
+             }
+             $test_cnt += count($test_files) - 1;
+             $test_idx--;
+             show_redirect_start($IN_REDIRECT['TESTS'], $tested, $tested_file);
+             // set up environment
+             $redirenv = array_merge($environment, $IN_REDIRECT['ENV']);
+             $redirenv['REDIR_TEST_DIR'] = realpath($IN_REDIRECT['TESTS']) . DIRECTORY_SEPARATOR;
+             usort($test_files, "test_sort");
+             run_all_tests($test_files, $redirenv, $tested);
+             show_redirect_ends($IN_REDIRECT['TESTS'], $tested, $tested_file);
+             // a redirected test never fails
+             $IN_REDIRECT = false;
+             junit_mark_test_as('PASS', $shortname, $tested);
+             return 'REDIR';
+         } else {
+             $bork_info = "Redirect info must contain exactly one TEST string to be used as redirect directory.";
 -            show_result("BORK", $bork_info, '', $temp_filenames);
++            show_result("BORK", $bork_info, '', '', $temp_filenames);
+             $PHP_FAILED_TESTS['BORKED'][] = array(
+                 'name' => $file,
+                 'test_name' => '',
+                 'output' => '',
+                 'diff' => '',
+                 'info' => "$bork_info [$file]",
+             );
+         }
+     }
  
- escape:
-       while ($test_files || $sequentialTests || $testsInProgress > 0) {
-               $toRead = array_values($workerSocks);
-               $toWrite = NULL;
-               $toExcept = NULL;
-               if (stream_select($toRead, $toWrite, $toExcept, 10)) {
-                       foreach ($toRead as $workerSock) {
-                               $i = array_search($workerSock, $workerSocks);
-                               if ($i === FALSE) {
-                                       kill_children($workerProcs);
-                                       error("Could not find worker stdout in array of worker stdouts, THIS SHOULD NOT HAPPEN.");
-                               }
-                               while (FALSE !== ($rawMessage = fgets($workerSock))) {
-                                       // work around fgets truncating things
-                                       if (($rawMessageBuffers[$i] ?? '') !== '') {
-                                               $rawMessage = $rawMessageBuffers[$i] . $rawMessage;
-                                               $rawMessageBuffers[$i] = '';
-                                       }
-                                       if (substr($rawMessage, -1) !== "\n") {
-                                               $rawMessageBuffers[$i] = $rawMessage;
-                                               continue;
-                                       }
-                                       $message = unserialize(base64_decode($rawMessage));
-                                       if (!$message) {
-                                               kill_children($workerProcs);
-                                               $stuff = fread($workerSock, 65536);
-                                               error("Could not decode message from worker $i: '$rawMessage$stuff'");
-                                       }
-                                       switch ($message["type"]) {
-                                               case "tests_finished":
-                                                       $testsInProgress--;
-                                                       foreach ($activeConflicts as $key => $workerId) {
-                                                               if ($workerId === $i) {
-                                                                       unset($activeConflicts[$key]);
-                                                                       if (isset($waitingTests[$key])) {
-                                                                               while ($test = array_pop($waitingTests[$key])) {
-                                                                                       $test_files[] = $test;
-                                                                               }
-                                                                               unset($waitingTests[$key]);
-                                                                       }
-                                                               }
-                                                       }
-                                                       if (junit_enabled()) {
-                                                               junit_merge_results($message["junit"]);
-                                                       }
-                                                       // intentional fall-through
-                                               case "ready":
-                                                       // Schedule sequential tests only once we are down to one worker.
-                                                       if (count($workerProcs) === 1 && $sequentialTests) {
-                                                               $test_files = array_merge($test_files, $sequentialTests);
-                                                               $sequentialTests = [];
-                                                       }
-                                                       // Batch multiple tests to reduce communication overhead.
-                                                       // - When valgrind is used, communication overhead is relatively small,
-                                                       //   so just use a batch size of 1.
-                                                       // - If this is running a small enough number of tests,
-                                                       //   reduce the batch size to give batches to more workers.
-                                                       $files = [];
-                                                       $maxBatchSize = $valgrind ? 1 : ($shuffle ? 4 : 32);
-                                                       $averageFilesPerWorker = max(1, (int)ceil($totalFileCount / count($workerProcs)));
-                                                       $batchSize = min($maxBatchSize, $averageFilesPerWorker);
-                                                       while (count($files) <= $batchSize && $file = array_pop($test_files)) {
-                                                               foreach ($fileConflictsWith[$file] as $conflictKey) {
-                                                                       if (isset($activeConflicts[$conflictKey])) {
-                                                                               $waitingTests[$conflictKey][] = $file;
-                                                                               continue 2;
-                                                                       }
-                                                               }
-                                                               $files[] = $file;
-                                                       }
-                                                       if ($files) {
-                                                               foreach ($files as $file) {
-                                                                       foreach ($fileConflictsWith[$file] as $conflictKey) {
-                                                                               $activeConflicts[$conflictKey] = $i;
-                                                                       }
-                                                               }
-                                                               $testsInProgress++;
-                                                               send_message($workerSocks[$i], [
-                                                                       "type" => "run_tests",
-                                                                       "test_files" => $files,
-                                                                       "env" => $env,
-                                                                       "redir_tested" => $redir_tested
-                                                               ]);
-                                                       } else {
-                                                               proc_terminate($workerProcs[$i]);
-                                                               unset($workerProcs[$i]);
-                                                               unset($workerSocks[$i]);
-                                                               goto escape;
-                                                       }
-                                                       break;
-                                               case "test_result":
-                                                       list($name, $index, $result, $resultText) = [$message["name"], $message["index"], $message["result"], $message["text"]];
-                                                       foreach ($message["PHP_FAILED_TESTS"] as $category => $tests) {
-                                                               $PHP_FAILED_TESTS[$category] = array_merge($PHP_FAILED_TESTS[$category], $tests);
-                                                       }
-                                                       $test_idx++;
-                                                       if (!$SHOW_ONLY_GROUPS) {
-                                                               clear_show_test();
-                                                       }
-                                                       echo $resultText;
-                                                       if (!$SHOW_ONLY_GROUPS) {
-                                                               show_test($test_idx, count($workerProcs) . "/$workers concurrent test workers running");
-                                                       }
-                                                       if (!is_array($name) && $result != 'REDIR') {
-                                                               $test_results[$index] = $result;
-                                                               if ($failed_tests_file && ($result == 'XFAILED' || $result == 'XLEAKED' || $result == 'FAILED' || $result == 'WARNED' || $result == 'LEAKED')) {
-                                                                       fwrite($failed_tests_file, "$index\n");
-                                                               }
-                                                               if ($result_tests_file) {
-                                                                       fwrite($result_tests_file, "$result\t$index\n");
-                                                               }
-                                                       }
-                                                       break;
-                                               case "error":
-                                                       kill_children($workerProcs);
-                                                       error("Worker $i reported error: $message[msg]");
-                                                       break;
-                                               case "php_error":
-                                                       kill_children($workerProcs);
-                                                       $error_consts = [
-                                                               'E_ERROR',
-                                                               'E_WARNING',
-                                                               'E_PARSE',
-                                                               'E_NOTICE',
-                                                               'E_CORE_ERROR',
-                                                               'E_CORE_WARNING',
-                                                               'E_COMPILE_ERROR',
-                                                               'E_COMPILE_WARNING',
-                                                               'E_USER_ERROR',
-                                                               'E_USER_WARNING',
-                                                               'E_USER_NOTICE',
-                                                               'E_STRICT', // TODO Cleanup when removed from Zend Engine.
-                                                               'E_RECOVERABLE_ERROR',
-                                                               'E_USER_DEPRECATED'
-                                                       ];
-                                                       $error_consts = array_combine(array_map('constant', $error_consts), $error_consts);
-                                                       error("Worker $i reported unexpected {$error_consts[$message['errno']]}: $message[errstr] in $message[errfile] on line $message[errline]");
-                                               default:
-                                                       kill_children($workerProcs);
-                                                       error("Unrecognised message type '$message[type]' from worker $i");
-                                       }
-                               }
-                       }
-               }
-       }
-       if (!$SHOW_ONLY_GROUPS) {
-               clear_show_test();
-       }
-       kill_children($workerProcs);
-       if ($testsInProgress < 0) {
-               error("$testsInProgress test batches “in progress”, which is less than zero. THIS SHOULD NOT HAPPEN.");
-       }
- }
+     if (is_array($org_file) || isset($section_text['REDIRECTTEST'])) {
  
- function send_message($stream, array $message) {
-       $blocking = stream_get_meta_data($stream)["blocked"];
-       stream_set_blocking($stream, true);
-       fwrite($stream, base64_encode(serialize($message)) . "\n");
-       stream_set_blocking($stream, $blocking);
- }
+         if (is_array($org_file)) {
+             $file = $org_file[0];
+         }
  
- function kill_children(array $children) {
-       foreach ($children as $child) {
-               if ($child) {
-                       proc_terminate($child);
-               }
-       }
- }
+         $bork_info = "Redirected test did not contain redirection info";
 -        show_result("BORK", $bork_info, '', $temp_filenames);
++        show_result("BORK", $bork_info, '', '', $temp_filenames);
+         $PHP_FAILED_TESTS['BORKED'][] = array(
+             'name' => $file,
+             'test_name' => '',
+             'output' => '',
+             'diff' => '',
+             'info' => "$bork_info [$file]",
+         );
  
- function run_worker() {
-       global $workerID, $workerSock;
-       $sockUri = getenv("TEST_PHP_URI");
-       $workerSock = stream_socket_client($sockUri, $_, $_, 5) or error("Couldn't connect to $sockUri");
-       $greeting = fgets($workerSock);
-       $greeting = unserialize(base64_decode($greeting)) or die("Could not decode greeting\n");
-       if ($greeting["type"] !== "hello" || $greeting["workerID"] !== $workerID) {
-               error("Unexpected greeting of type $greeting[type] and for worker $greeting[workerID]");
-       }
-       set_error_handler(function ($errno, $errstr, $errfile, $errline) use ($workerSock) {
-               if (error_reporting() & $errno) {
-                       send_message($workerSock, compact('errno', 'errstr', 'errfile', 'errline') + [
-                               'type' => 'php_error'
-                       ]);
-               }
-               return true;
-       });
-       foreach ($greeting["GLOBALS"] as $var => $value) {
-               if ($var !== "workerID" && $var !== "workerSock" && $var !== "GLOBALS") {
-                       $GLOBALS[$var] = $value;
-               }
-       }
-       foreach ($greeting["constants"] as $const => $value) {
-               define($const, $value);
-       }
-       send_message($workerSock, [
-               "type" => "hello_reply",
-               "workerID" => $workerID
-       ]);
-       send_message($workerSock, [
-               "type" => "ready"
-       ]);
-       while (($command = fgets($workerSock))) {
-               $command = unserialize(base64_decode($command));
-               switch ($command["type"]) {
-                       case "run_tests":
-                               run_all_tests($command["test_files"], $command["env"], $command["redir_tested"]);
-                               send_message($workerSock, [
-                                       "type" => "tests_finished",
-                                       "junit" => junit_enabled() ? $GLOBALS['JUNIT'] : null,
-                               ]);
-                               junit_init();
-                               break;
-                       default:
-                               send_message($workerSock, [
-                                       "type" => "error",
-                                       "msg" => "Unrecognised message type: $command[type]"
-                               ]);
-                               break 2;
-               }
-       }
- }
+         junit_mark_test_as('BORK', $shortname, $tested, null, $bork_info);
  
- //
- //  Show file or result block
- //
- function show_file_block($file, $block, $section = null)
- {
-       global $cfg;
+         return 'BORKED';
+     }
  
-       if ($cfg['show'][$file]) {
+     // We've satisfied the preconditions - run the test!
+     if (isset($section_text['FILE'])) {
+         show_file_block('php', $section_text['FILE'], 'TEST');
+         save_text($test_file, $section_text['FILE'], $temp_file);
+     } else {
+         $test_file = $temp_file = "";
+     }
  
-               if (is_null($section)) {
-                       $section = strtoupper($file);
-               }
+     if (array_key_exists('GET', $section_text)) {
+         $query_string = trim($section_text['GET']);
+     } else {
+         $query_string = '';
+     }
  
-               echo "\n========" . $section . "========\n";
-               echo rtrim($block);
-               echo "\n========DONE========\n";
-       }
- }
+     $env['REDIRECT_STATUS'] = '1';
+     if (empty($env['QUERY_STRING'])) {
+         $env['QUERY_STRING'] = $query_string;
+     }
+     if (empty($env['PATH_TRANSLATED'])) {
+         $env['PATH_TRANSLATED'] = $test_file;
+     }
+     if (empty($env['SCRIPT_FILENAME'])) {
+         $env['SCRIPT_FILENAME'] = $test_file;
+     }
  
- //
- //  Run an individual test case.
- //
- function run_test($php, $file, $env)
- {
-       global $log_format, $ini_overwrites, $PHP_FAILED_TESTS;
-       global $pass_options, $DETAILED, $IN_REDIRECT, $test_cnt, $test_idx;
-       global $valgrind, $temp_source, $temp_target, $cfg, $environment;
-       global $no_clean;
-       global $SHOW_ONLY_GROUPS;
-       global $no_file_cache;
-       global $slow_min_ms;
-       global $preload;
-       // Parallel testing
-       global $workerID;
-       $temp_filenames = null;
-       $org_file = $file;
-       if (isset($env['TEST_PHP_CGI_EXECUTABLE'])) {
-               $php_cgi = $env['TEST_PHP_CGI_EXECUTABLE'];
-       }
-       if (isset($env['TEST_PHPDBG_EXECUTABLE'])) {
-               $phpdbg = $env['TEST_PHPDBG_EXECUTABLE'];
-       }
-       if (is_array($file)) {
-               $file = $file[0];
-       }
-       if ($DETAILED) echo "
- =================
- TEST $file
- ";
+     if (array_key_exists('COOKIE', $section_text)) {
+         $env['HTTP_COOKIE'] = trim($section_text['COOKIE']);
+     } else {
+         $env['HTTP_COOKIE'] = '';
+     }
  
-       // Load the sections of the test file.
-       $section_text = array('TEST' => '');
-       $fp = fopen($file, "rb") or error("Cannot open test file: $file");
-       $bork_info = null;
-       if (!feof($fp)) {
-               $line = fgets($fp);
-               if ($line === false) {
-                       $bork_info = "cannot read test";
-               }
-       } else {
-               $bork_info = "empty test [$file]";
-       }
-       if ($bork_info === null && strncmp('--TEST--', $line, 8)) {
-               $bork_info = "tests must start with --TEST-- [$file]";
-       }
-       $section = 'TEST';
-       $secfile = false;
-       $secdone = false;
-       while (!feof($fp)) {
-               $line = fgets($fp);
-               if ($line === false) {
-                       break;
-               }
-               // Match the beginning of a section.
-               if (preg_match('/^--([_A-Z]+)--/', $line, $r)) {
-                       $section = (string)$r[1];
-                       if (isset($section_text[$section]) && $section_text[$section]) {
-                               $bork_info = "duplicated $section section";
-                       }
-                       // check for unknown sections
-                       if (!in_array($section, array(
-                               'EXPECT', 'EXPECTF', 'EXPECTREGEX', 'EXPECTREGEX_EXTERNAL', 'EXPECT_EXTERNAL', 'EXPECTF_EXTERNAL', 'EXPECTHEADERS',
-                               'POST', 'POST_RAW', 'GZIP_POST', 'DEFLATE_POST', 'PUT', 'GET', 'COOKIE', 'ARGS',
-                               'FILE', 'FILEEOF', 'FILE_EXTERNAL', 'REDIRECTTEST',
-                               'CAPTURE_STDIO', 'STDIN', 'CGI', 'PHPDBG',
-                               'INI', 'ENV', 'EXTENSIONS',
-                               'SKIPIF', 'XFAIL', 'XLEAK', 'CLEAN',
-                               'CREDITS', 'DESCRIPTION', 'CONFLICTS', 'WHITESPACE_SENSITIVE',
-                       ))) {
-                               $bork_info = 'Unknown section "' . $section . '"';
-                       }
-                       $section_text[$section] = '';
-                       $secfile = $section == 'FILE' || $section == 'FILEEOF' || $section == 'FILE_EXTERNAL';
-                       $secdone = false;
-                       continue;
-               }
-               // Add to the section text.
-               if (!$secdone) {
-                       $section_text[$section] .= $line;
-               }
-               // End of actual test?
-               if ($secfile && preg_match('/^===DONE===\s*$/', $line)) {
-                       $secdone = true;
-               }
-       }
-       // the redirect section allows a set of tests to be reused outside of
-       // a given test dir
-       if ($bork_info === null) {
-               if (isset($section_text['REDIRECTTEST'])) {
-                       if ($IN_REDIRECT) {
-                               $bork_info = "Can't redirect a test from within a redirected test";
-                       }
-               } else {
-                       if (!isset($section_text['PHPDBG']) && isset($section_text['FILE']) + isset($section_text['FILEEOF']) + isset($section_text['FILE_EXTERNAL']) != 1) {
-                               $bork_info = "missing section --FILE--";
-                       }
-                       if (isset($section_text['FILEEOF'])) {
-                               $section_text['FILE'] = preg_replace("/[\r\n]+$/", '', $section_text['FILEEOF']);
-                               unset($section_text['FILEEOF']);
-                       }
-                       foreach (array('FILE', 'EXPECT', 'EXPECTF', 'EXPECTREGEX') as $prefix) {
-                               $key = $prefix . '_EXTERNAL';
-                               if (isset($section_text[$key])) {
-                                       // don't allow tests to retrieve files from anywhere but this subdirectory
-                                       $section_text[$key] = dirname($file) . '/' . trim(str_replace('..', '', $section_text[$key]));
-                                       if (file_exists($section_text[$key])) {
-                                               $section_text[$prefix] = file_get_contents($section_text[$key], FILE_BINARY);
-                                               unset($section_text[$key]);
-                                       } else {
-                                               $bork_info = "could not load --" . $key . "-- " . dirname($file) . '/' . trim($section_text[$key]);
-                                       }
-                               }
-                       }
-                       if ((isset($section_text['EXPECT']) + isset($section_text['EXPECTF']) + isset($section_text['EXPECTREGEX'])) != 1) {
-                               $bork_info = "missing section --EXPECT--, --EXPECTF-- or --EXPECTREGEX--";
-                       }
-               }
-       }
-       fclose($fp);
-       $shortname = str_replace(TEST_PHP_SRCDIR . '/', '', $file);
-       $tested_file = $shortname;
-       if ($bork_info !== null) {
-               show_result("BORK", $bork_info, $tested_file);
-               $PHP_FAILED_TESTS['BORKED'][] = array(
-                       'name' => $file,
-                       'test_name' => '',
-                       'output' => '',
-                       'diff' => '',
-                       'info' => "$bork_info [$file]",
-               );
-               junit_mark_test_as('BORK', $shortname, $tested_file, 0, $bork_info);
-               return 'BORKED';
-       }
-       if (isset($section_text['CAPTURE_STDIO'])) {
-               $captureStdIn = stripos($section_text['CAPTURE_STDIO'], 'STDIN') !== false;
-               $captureStdOut = stripos($section_text['CAPTURE_STDIO'], 'STDOUT') !== false;
-               $captureStdErr = stripos($section_text['CAPTURE_STDIO'], 'STDERR') !== false;
-       } else {
-               $captureStdIn = true;
-               $captureStdOut = true;
-               $captureStdErr = true;
-       }
-       if ($captureStdOut && $captureStdErr) {
-               $cmdRedirect = ' 2>&1';
-       } else {
-               $cmdRedirect = '';
-       }
-       $tested = trim($section_text['TEST']);
-       /* For GET/POST/PUT tests, check if cgi sapi is available and if it is, use it. */
-       if (array_key_exists('CGI', $section_text) || !empty($section_text['GET']) || !empty($section_text['POST']) || !empty($section_text['GZIP_POST']) || !empty($section_text['DEFLATE_POST']) || !empty($section_text['POST_RAW']) || !empty($section_text['PUT']) || !empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) {
-               if (isset($php_cgi)) {
-                       $php = $php_cgi . ' -C ';
-               } else if (IS_WINDOWS && file_exists(dirname($php) . "/php-cgi.exe")) {
-                       $php = realpath(dirname($php) . "/php-cgi.exe") . ' -C ';
-               } else {
-                       if (file_exists(dirname($php) . "/../../sapi/cgi/php-cgi")) {
-                               $php = realpath(dirname($php) . "/../../sapi/cgi/php-cgi") . ' -C ';
-                       } else if (file_exists("./sapi/cgi/php-cgi")) {
-                               $php = realpath("./sapi/cgi/php-cgi") . ' -C ';
-                       } else if (file_exists(dirname($php) . "/php-cgi")) {
-                               $php = realpath(dirname($php) . "/php-cgi") . ' -C ';
-                       } else {
-                               show_result('SKIP', $tested, $tested_file, "reason: CGI not available");
-                               junit_init_suite(junit_get_suitename_for($shortname));
-                               junit_mark_test_as('SKIP', $shortname, $tested, 0, 'CGI not available');
-                               return 'SKIPPED';
-                       }
-               }
-               $uses_cgi = true;
-       }
-       /* For phpdbg tests, check if phpdbg sapi is available and if it is, use it. */
-       $extra_options = '';
-       if (array_key_exists('PHPDBG', $section_text)) {
-               if (!isset($section_text['STDIN'])) {
-                       $section_text['STDIN'] = $section_text['PHPDBG'] . "\n";
-               }
-               if (isset($phpdbg)) {
-                       $php = $phpdbg . ' -qIb';
-                       // Additional phpdbg command line options for sections that need to
-                       // be run straight away. For example, EXTENSIONS, SKIPIF, CLEAN.
-                       $extra_options = '-rr';
-               } else {
-                       show_result('SKIP', $tested, $tested_file, "reason: phpdbg not available");
-                       junit_init_suite(junit_get_suitename_for($shortname));
-                       junit_mark_test_as('SKIP', $shortname, $tested, 0, 'phpdbg not available');
-                       return 'SKIPPED';
-               }
-       }
-       if (!$SHOW_ONLY_GROUPS && !$workerID) {
-               show_test($test_idx, $shortname);
-       }
-       if (is_array($IN_REDIRECT)) {
-               $temp_dir = $test_dir = $IN_REDIRECT['dir'];
-       } else {
-               $temp_dir = $test_dir = realpath(dirname($file));
-       }
-       if ($temp_source && $temp_target) {
-               $temp_dir = str_replace($temp_source, $temp_target, $temp_dir);
-       }
-       $main_file_name = basename($file, 'phpt');
-       $diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'diff';
-       $log_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'log';
-       $exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'exp';
-       $output_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'out';
-       $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'mem';
-       $sh_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'sh';
-       $temp_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'php';
-       $test_file = $test_dir . DIRECTORY_SEPARATOR . $main_file_name . 'php';
-       $temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'skip.php';
-       $test_skipif = $test_dir . DIRECTORY_SEPARATOR . $main_file_name . 'skip.php';
-       $temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'clean.php';
-       $test_clean = $test_dir . DIRECTORY_SEPARATOR . $main_file_name . 'clean.php';
-       $preload_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'preload.php';
-       $tmp_post = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'post';
-       $tmp_relative_file = str_replace(__DIR__ . DIRECTORY_SEPARATOR, '', $test_file) . 't';
-       if ($temp_source && $temp_target) {
-               $temp_skipif .= 's';
-               $temp_file .= 's';
-               $temp_clean .= 's';
-               $copy_file = $temp_dir . DIRECTORY_SEPARATOR . basename(is_array($file) ? $file[1] : $file) . '.phps';
-               if (!is_dir(dirname($copy_file))) {
-                       mkdir(dirname($copy_file), 0777, true) or error("Cannot create output directory - " . dirname($copy_file));
-               }
-               if (isset($section_text['FILE'])) {
-                       save_text($copy_file, $section_text['FILE']);
-               }
-               $temp_filenames = array(
-                       'file' => $copy_file,
-                       'diff' => $diff_filename,
-                       'log' => $log_filename,
-                       'exp' => $exp_filename,
-                       'out' => $output_filename,
-                       'mem' => $memcheck_filename,
-                       'sh' => $sh_filename,
-                       'php' => $temp_file,
-                       'skip' => $temp_skipif,
-                       'clean' => $temp_clean
-               );
-       }
-       if (is_array($IN_REDIRECT)) {
-               $tested = $IN_REDIRECT['prefix'] . ' ' . trim($section_text['TEST']);
-               $tested_file = $tmp_relative_file;
-               $shortname = str_replace(TEST_PHP_SRCDIR . '/', '', $tested_file);
-       }
-       // unlink old test results
-       @unlink($diff_filename);
-       @unlink($log_filename);
-       @unlink($exp_filename);
-       @unlink($output_filename);
-       @unlink($memcheck_filename);
-       @unlink($sh_filename);
-       @unlink($temp_file);
-       @unlink($test_file);
-       @unlink($temp_skipif);
-       @unlink($test_skipif);
-       @unlink($tmp_post);
-       @unlink($temp_clean);
-       @unlink($test_clean);
-       @unlink($preload_filename);
-       // Reset environment from any previous test.
-       $env['REDIRECT_STATUS'] = '';
-       $env['QUERY_STRING'] = '';
-       $env['PATH_TRANSLATED'] = '';
-       $env['SCRIPT_FILENAME'] = '';
-       $env['REQUEST_METHOD'] = '';
-       $env['CONTENT_TYPE'] = '';
-       $env['CONTENT_LENGTH'] = '';
-       $env['TZ'] = '';
-       if (!empty($section_text['ENV'])) {
-               foreach (explode("\n", trim($section_text['ENV'])) as $e) {
-                       $e = explode('=', trim($e), 2);
-                       if (!empty($e[0]) && isset($e[1])) {
-                               $env[$e[0]] = $e[1];
-                       }
-               }
-       }
-       // Default ini settings
-       $ini_settings = $workerID ? array('opcache.cache_id' => "worker$workerID") : array();
-       // Additional required extensions
-       if (array_key_exists('EXTENSIONS', $section_text)) {
-               $ext_params = array();
-               settings2array($ini_overwrites, $ext_params);
-               $ext_params = settings2params($ext_params);
-               $ext_dir = `$php $pass_options $extra_options $ext_params -d display_errors=0 -r "echo ini_get('extension_dir');"`;
-               $extensions = preg_split("/[\n\r]+/", trim($section_text['EXTENSIONS']));
-               $loaded = explode(",", `$php $pass_options $extra_options $ext_params -d display_errors=0 -r "echo implode(',', get_loaded_extensions());"`);
-               $ext_prefix = IS_WINDOWS ? "php_" : "";
-               foreach ($extensions as $req_ext) {
-                       if (!in_array($req_ext, $loaded)) {
-                               if ($req_ext == 'opcache') {
-                                       $ini_settings['zend_extension'][] = $ext_dir . DIRECTORY_SEPARATOR . $ext_prefix . $req_ext . '.' . PHP_SHLIB_SUFFIX;
-                               } else {
-                                       $ini_settings['extension'][] = $ext_dir . DIRECTORY_SEPARATOR . $ext_prefix . $req_ext . '.' . PHP_SHLIB_SUFFIX;
-                               }
-                       }
-               }
-       }
-       // additional ini overwrites
-       //$ini_overwrites[] = 'setting=value';
-       settings2array($ini_overwrites, $ini_settings);
-       $orig_ini_settings = settings2params($ini_settings);
-       // Any special ini settings
-       // these may overwrite the test defaults...
-       if (array_key_exists('INI', $section_text)) {
-               $section_text['INI'] = str_replace('{PWD}', dirname($file), $section_text['INI']);
-               $section_text['INI'] = str_replace('{TMP}', sys_get_temp_dir(), $section_text['INI']);
-               $replacement = IS_WINDOWS ? '"' . PHP_BINARY . ' -r \"while ($in = fgets(STDIN)) echo $in;\" > $1"' : 'tee $1 >/dev/null';
-               $section_text['INI'] = preg_replace('/{MAIL:(\S+)}/', $replacement, $section_text['INI']);
-               settings2array(preg_split("/[\n\r]+/", $section_text['INI']), $ini_settings);
-       }
-       $ini_settings = settings2params($ini_settings);
-       $env['TEST_PHP_EXTRA_ARGS'] = $pass_options . ' ' . $ini_settings;
-       // Check if test should be skipped.
-       $info = '';
-       $warn = false;
-       if (array_key_exists('SKIPIF', $section_text)) {
-               if (trim($section_text['SKIPIF'])) {
-                       show_file_block('skip', $section_text['SKIPIF']);
-                       save_text($test_skipif, $section_text['SKIPIF'], $temp_skipif);
-                       $extra = !IS_WINDOWS ?
-                               "unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;" : "";
-                       if ($valgrind) {
-                               $env['USE_ZEND_ALLOC'] = '0';
-                               $env['ZEND_DONT_UNLOAD_MODULES'] = 1;
-                       }
-                       junit_start_timer($shortname);
-                       $output = system_with_timeout("$extra $php $pass_options $extra_options -q $orig_ini_settings $no_file_cache -d display_errors=1 -d display_startup_errors=0 \"$test_skipif\"", $env);
-                       $output = trim($output);
-                       junit_finish_timer($shortname);
-                       if (!$cfg['keep']['skip']) {
-                               @unlink($test_skipif);
-                       }
-                       if (!strncasecmp('skip', $output, 4)) {
-                               if (preg_match('/^skip\s*(.+)/i', $output, $m)) {
-                                       show_result('SKIP', $tested, $tested_file, "reason: $m[1]", $temp_filenames);
-                               } else {
-                                       show_result('SKIP', $tested, $tested_file, '', $temp_filenames);
-                               }
-                               if (!$cfg['keep']['skip']) {
-                                       @unlink($test_skipif);
-                               }
-                               $message = !empty($m[1]) ? $m[1] : '';
-                               junit_mark_test_as('SKIP', $shortname, $tested, null, $message);
-                               return 'SKIPPED';
-                       }
-                       if (!strncasecmp('info', $output, 4) && preg_match('/^info\s*(.+)/i', $output, $m)) {
-                               $info = " (info: $m[1])";
-                       } elseif (!strncasecmp('warn', $output, 4) && preg_match('/^warn\s+(.+)/i', $output, $m)) {
-                               $warn = true; /* only if there is a reason */
-                               $info = " (warn: $m[1])";
-                       } elseif (!strncasecmp('xfail', $output, 5)) {
-                               // Pretend we have an XFAIL section
-                               $section_text['XFAIL'] = ltrim(substr($output, 5));
-                       } elseif ($output !== '') {
-                               show_result("BORK", $output, $tested_file, 'reason: invalid output from SKIPIF', $temp_filenames);
-                               $PHP_FAILED_TESTS['BORKED'][] = array(
-                                       'name' => $file,
-                                       'test_name' => '',
-                                       'output' => '',
-                                       'diff' => '',
-                                       'info' => "$output [$file]",
-                               );
-                               junit_mark_test_as('BORK', $shortname, $tested, null, $output);
-                               return 'BORKED';
-                       }
-               }
-       }
-       if (!extension_loaded("zlib")
-               && (array_key_exists("GZIP_POST", $section_text)
-               || array_key_exists("DEFLATE_POST", $section_text))) {
-               $message = "ext/zlib required";
-               show_result('SKIP', $tested, $tested_file, "reason: $message", $temp_filenames);
-               junit_mark_test_as('SKIP', $shortname, $tested, null, $message);
-               return 'SKIPPED';
-       }
-       if (isset($section_text['REDIRECTTEST'])) {
-               $test_files = array();
-               $IN_REDIRECT = eval($section_text['REDIRECTTEST']);
-               $IN_REDIRECT['via'] = "via [$shortname]\n\t";
-               $IN_REDIRECT['dir'] = realpath(dirname($file));
-               $IN_REDIRECT['prefix'] = trim($section_text['TEST']);
-               if (!empty($IN_REDIRECT['TESTS'])) {
-                       if (is_array($org_file)) {
-                               $test_files[] = $org_file[1];
-                       } else {
-                               $GLOBALS['test_files'] = $test_files;
-                               find_files($IN_REDIRECT['TESTS']);
-                               foreach ($GLOBALS['test_files'] as $f) {
-                                       $test_files[] = array($f, $file);
-                               }
-                       }
-                       $test_cnt += count($test_files) - 1;
-                       $test_idx--;
-                       show_redirect_start($IN_REDIRECT['TESTS'], $tested, $tested_file);
-                       // set up environment
-                       $redirenv = array_merge($environment, $IN_REDIRECT['ENV']);
-                       $redirenv['REDIR_TEST_DIR'] = realpath($IN_REDIRECT['TESTS']) . DIRECTORY_SEPARATOR;
-                       usort($test_files, "test_sort");
-                       run_all_tests($test_files, $redirenv, $tested);
-                       show_redirect_ends($IN_REDIRECT['TESTS'], $tested, $tested_file);
-                       // a redirected test never fails
-                       $IN_REDIRECT = false;
-                       junit_mark_test_as('PASS', $shortname, $tested);
-                       return 'REDIR';
-               } else {
-                       $bork_info = "Redirect info must contain exactly one TEST string to be used as redirect directory.";
-                       show_result("BORK", $bork_info, '', '', $temp_filenames);
-                       $PHP_FAILED_TESTS['BORKED'][] = array(
-                               'name' => $file,
-                               'test_name' => '',
-                               'output' => '',
-                               'diff' => '',
-                               'info' => "$bork_info [$file]",
-                       );
-               }
-       }
-       if (is_array($org_file) || isset($section_text['REDIRECTTEST'])) {
-               if (is_array($org_file)) {
-                       $file = $org_file[0];
-               }
-               $bork_info = "Redirected test did not contain redirection info";
-               show_result("BORK", $bork_info, '', '', $temp_filenames);
-               $PHP_FAILED_TESTS['BORKED'][] = array(
-                       'name' => $file,
-                       'test_name' => '',
-                       'output' => '',
-                       'diff' => '',
-                       'info' => "$bork_info [$file]",
-               );
-               junit_mark_test_as('BORK', $shortname, $tested, null, $bork_info);
-               return 'BORKED';
-       }
-       // We've satisfied the preconditions - run the test!
-       if (isset($section_text['FILE'])) {
-               show_file_block('php', $section_text['FILE'], 'TEST');
-               save_text($test_file, $section_text['FILE'], $temp_file);
-       } else {
-               $test_file = $temp_file = "";
-       }
-       if (array_key_exists('GET', $section_text)) {
-               $query_string = trim($section_text['GET']);
-       } else {
-               $query_string = '';
-       }
-       $env['REDIRECT_STATUS'] = '1';
-       if (empty($env['QUERY_STRING'])) {
-               $env['QUERY_STRING'] = $query_string;
-       }
-       if (empty($env['PATH_TRANSLATED'])) {
-               $env['PATH_TRANSLATED'] = $test_file;
-       }
-       if (empty($env['SCRIPT_FILENAME'])) {
-               $env['SCRIPT_FILENAME'] = $test_file;
-       }
-       if (array_key_exists('COOKIE', $section_text)) {
-               $env['HTTP_COOKIE'] = trim($section_text['COOKIE']);
-       } else {
-               $env['HTTP_COOKIE'] = '';
-       }
-       $args = isset($section_text['ARGS']) ? ' -- ' . $section_text['ARGS'] : '';
+     $args = isset($section_text['ARGS']) ? ' -- ' . $section_text['ARGS'] : '';
+     if ($preload && !empty($test_file)) {
+         save_text($preload_filename, "<?php opcache_compile_file('$test_file');");
+         $local_pass_options = $pass_options;
+         unset($pass_options);
+         $pass_options = $local_pass_options;
+         $pass_options .= " -d opcache.preload=" . $preload_filename;
+     }
  
-       if ($preload && !empty($test_file)) {
-               save_text($preload_filename, "<?php opcache_compile_file('$test_file');");
-               $local_pass_options = $pass_options;
-               unset($pass_options);
-               $pass_options = $local_pass_options;
-               $pass_options .= " -d opcache.preload=" . $preload_filename;
-       }
+     if (array_key_exists('POST_RAW', $section_text) && !empty($section_text['POST_RAW'])) {
  
-       if (array_key_exists('POST_RAW', $section_text) && !empty($section_text['POST_RAW'])) {
+         $post = trim($section_text['POST_RAW']);
+         $raw_lines = explode("\n", $post);
  
-               $post = trim($section_text['POST_RAW']);
-               $raw_lines = explode("\n", $post);
+         $request = '';
+         $started = false;
  
-               $request = '';
-               $started = false;
+         foreach ($raw_lines as $line) {
  
-               foreach ($raw_lines as $line) {
-                       if (empty($env['CONTENT_TYPE']) && preg_match('/^Content-Type:(.*)/i', $line, $res)) {
-                               $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1]));
-                               continue;
-                       }
+             if (empty($env['CONTENT_TYPE']) && preg_match('/^Content-Type:(.*)/i', $line, $res)) {
+                 $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1]));
+                 continue;
+             }
  
-                       if ($started) {
-                               $request .= "\n";
-                       }
+             if ($started) {
+                 $request .= "\n";
+             }
  
-                       $started = true;
-                       $request .= $line;
-               }
+             $started = true;
+             $request .= $line;
+         }
  
-               $env['CONTENT_LENGTH'] = strlen($request);
-               $env['REQUEST_METHOD'] = 'POST';
+         $env['CONTENT_LENGTH'] = strlen($request);
+         $env['REQUEST_METHOD'] = 'POST';
  
-               if (empty($request)) {
-                       junit_mark_test_as('BORK', $shortname, $tested, null, 'empty $request');
-                       return 'BORKED';
-               }
+         if (empty($request)) {
+             junit_mark_test_as('BORK', $shortname, $tested, null, 'empty $request');
+             return 'BORKED';
+         }
  
-               save_text($tmp_post, $request);
-               $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
+         save_text($tmp_post, $request);
+         $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
  
-       } elseif (array_key_exists('PUT', $section_text) && !empty($section_text['PUT'])) {
+     } elseif (array_key_exists('PUT', $section_text) && !empty($section_text['PUT'])) {
  
-               $post = trim($section_text['PUT']);
-               $raw_lines = explode("\n", $post);
+         $post = trim($section_text['PUT']);
+         $raw_lines = explode("\n", $post);
  
-               $request = '';
-               $started = false;
+         $request = '';
+         $started = false;
  
-               foreach ($raw_lines as $line) {
+         foreach ($raw_lines as $line) {
  
-                       if (empty($env['CONTENT_TYPE']) && preg_match('/^Content-Type:(.*)/i', $line, $res)) {
-                               $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1]));
-                               continue;
-                       }
+             if (empty($env['CONTENT_TYPE']) && preg_match('/^Content-Type:(.*)/i', $line, $res)) {
+                 $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1]));
+                 continue;
+             }
  
-                       if ($started) {
-                               $request .= "\n";
-                       }
+             if ($started) {
+                 $request .= "\n";
+             }
  
-                       $started = true;
-                       $request .= $line;
-               }
+             $started = true;
+             $request .= $line;
+         }
  
-               $env['CONTENT_LENGTH'] = strlen($request);
-               $env['REQUEST_METHOD'] = 'PUT';
+         $env['CONTENT_LENGTH'] = strlen($request);
+         $env['REQUEST_METHOD'] = 'PUT';
  
-               if (empty($request)) {
-                       junit_mark_test_as('BORK', $shortname, $tested, null, 'empty $request');
-                       return 'BORKED';
-               }
+         if (empty($request)) {
+             junit_mark_test_as('BORK', $shortname, $tested, null, 'empty $request');
+             return 'BORKED';
+         }
  
-               save_text($tmp_post, $request);
-               $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
+         save_text($tmp_post, $request);
+         $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
  
-       } else if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) {
+     } else if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) {
  
-               $post = trim($section_text['POST']);
-               $content_length = strlen($post);
-               save_text($tmp_post, $post);
+         $post = trim($section_text['POST']);
+         $content_length = strlen($post);
+         save_text($tmp_post, $post);
  
-               $env['REQUEST_METHOD'] = 'POST';
-               if (empty($env['CONTENT_TYPE'])) {
-                       $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
-               }
+         $env['REQUEST_METHOD'] = 'POST';
+         if (empty($env['CONTENT_TYPE'])) {
+             $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
+         }
  
-               if (empty($env['CONTENT_LENGTH'])) {
-                       $env['CONTENT_LENGTH'] = $content_length;
-               }
+         if (empty($env['CONTENT_LENGTH'])) {
+             $env['CONTENT_LENGTH'] = $content_length;
+         }
  
-               $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
+         $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
  
-       } else if (array_key_exists('GZIP_POST', $section_text) && !empty($section_text['GZIP_POST'])) {
+     } else if (array_key_exists('GZIP_POST', $section_text) && !empty($section_text['GZIP_POST'])) {
  
-               $post = trim($section_text['GZIP_POST']);
-               $post = gzencode($post, 9, FORCE_GZIP);
-               $env['HTTP_CONTENT_ENCODING'] = 'gzip';
+         $post = trim($section_text['GZIP_POST']);
+         $post = gzencode($post, 9, FORCE_GZIP);
+         $env['HTTP_CONTENT_ENCODING'] = 'gzip';
  
-               save_text($tmp_post, $post);
-               $content_length = strlen($post);
+         save_text($tmp_post, $post);
+         $content_length = strlen($post);
  
-               $env['REQUEST_METHOD'] = 'POST';
-               $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
-               $env['CONTENT_LENGTH'] = $content_length;
+         $env['REQUEST_METHOD'] = 'POST';
+         $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
+         $env['CONTENT_LENGTH'] = $content_length;
  
-               $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
+         $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
  
-       } else if (array_key_exists('DEFLATE_POST', $section_text) && !empty($section_text['DEFLATE_POST'])) {
-               $post = trim($section_text['DEFLATE_POST']);
-               $post = gzcompress($post, 9);
-               $env['HTTP_CONTENT_ENCODING'] = 'deflate';
-               save_text($tmp_post, $post);
-               $content_length = strlen($post);
+     } else if (array_key_exists('DEFLATE_POST', $section_text) && !empty($section_text['DEFLATE_POST'])) {
+         $post = trim($section_text['DEFLATE_POST']);
+         $post = gzcompress($post, 9);
+         $env['HTTP_CONTENT_ENCODING'] = 'deflate';
+         save_text($tmp_post, $post);
+         $content_length = strlen($post);
  
-               $env['REQUEST_METHOD'] = 'POST';
-               $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
-               $env['CONTENT_LENGTH'] = $content_length;
+         $env['REQUEST_METHOD'] = 'POST';
+         $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
+         $env['CONTENT_LENGTH'] = $content_length;
  
-               $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
+         $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
  
-       } else {
+     } else {
  
-               $env['REQUEST_METHOD'] = 'GET';
-               $env['CONTENT_TYPE'] = '';
-               $env['CONTENT_LENGTH'] = '';
+         $env['REQUEST_METHOD'] = 'GET';
+         $env['CONTENT_TYPE'] = '';
+         $env['CONTENT_LENGTH'] = '';
  
-               $cmd = "$php $pass_options $ini_settings -f \"$test_file\" $args$cmdRedirect";
-       }
+         $cmd = "$php $pass_options $ini_settings -f \"$test_file\" $args$cmdRedirect";
+     }
  
-       if ($valgrind) {
-               $env['USE_ZEND_ALLOC'] = '0';
-               $env['ZEND_DONT_UNLOAD_MODULES'] = 1;
+     if ($valgrind) {
+         $env['USE_ZEND_ALLOC'] = '0';
+         $env['ZEND_DONT_UNLOAD_MODULES'] = 1;
  
-               $cmd = $valgrind->wrapCommand($cmd, $memcheck_filename, strpos($test_file, "pcre") !== false);
-       }
+         $cmd = $valgrind->wrapCommand($cmd, $memcheck_filename, strpos($test_file, "pcre") !== false);
+     }
  
-       if ($DETAILED) echo "
+     if ($DETAILED) echo "
  CONTENT_LENGTH  = " . $env['CONTENT_LENGTH'] . "
  CONTENT_TYPE    = " . $env['CONTENT_TYPE'] . "
  PATH_TRANSLATED = " . $env['PATH_TRANSLATED'] . "
@@@ -2463,289 -2446,289 +2463,289 @@@ HTTP_COOKIE     = " . $env['HTTP_COOKIE
  COMMAND $cmd
  ";
  
-       junit_start_timer($shortname);
-       $hrtime = hrtime();
-       $startTime = $hrtime[0] * 1000000000 + $hrtime[1];
-       $out = system_with_timeout($cmd, $env, $section_text['STDIN'] ?? null, $captureStdIn, $captureStdOut, $captureStdErr);
-       junit_finish_timer($shortname);
-       $hrtime = hrtime();
-       $time = $hrtime[0] * 1000000000 + $hrtime[1] - $startTime;
-       if ($time >= $slow_min_ms * 1000000) {
-               $PHP_FAILED_TESTS['SLOW'][] = array(
-                       'name' => $file,
-                       'test_name' => (is_array($IN_REDIRECT) ? $IN_REDIRECT['via'] : '') . $tested . " [$tested_file]",
-                       'output' => '',
-                       'diff' => '',
-                       'info' => $time / 1000000000,
-               );
-       }
-       if (array_key_exists('CLEAN', $section_text) && (!$no_clean || $cfg['keep']['clean'])) {
-               if (trim($section_text['CLEAN'])) {
-                       show_file_block('clean', $section_text['CLEAN']);
-                       save_text($test_clean, trim($section_text['CLEAN']), $temp_clean);
-                       if (!$no_clean) {
-                               $clean_params = array();
-                               settings2array($ini_overwrites, $clean_params);
-                               $clean_params = settings2params($clean_params);
-                               $extra = !IS_WINDOWS ?
-                                       "unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;" : "";
-                               system_with_timeout("$extra $php $pass_options $extra_options -q $clean_params $no_file_cache \"$test_clean\"", $env);
-                       }
-                       if (!$cfg['keep']['clean']) {
-                               @unlink($test_clean);
-                       }
-               }
-       }
-       @unlink($preload_filename);
-       $leaked = false;
-       $passed = false;
-       if ($valgrind) { // leak check
-               $leaked = filesize($memcheck_filename) > 0;
-               if (!$leaked) {
-                       @unlink($memcheck_filename);
-               }
-       }
-       // Does the output match what is expected?
-       $output = preg_replace("/\r\n/", "\n", trim($out));
-       /* when using CGI, strip the headers from the output */
-       $headers = array();
-       if (!empty($uses_cgi) && preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $out, $match)) {
-               $output = trim($match[2]);
-               $rh = preg_split("/[\n\r]+/", $match[1]);
-               foreach ($rh as $line) {
-                       if (strpos($line, ':') !== false) {
-                               $line = explode(':', $line, 2);
-                               $headers[trim($line[0])] = trim($line[1]);
-                       }
-               }
-       }
-       $failed_headers = false;
-       if (isset($section_text['EXPECTHEADERS'])) {
-               $want = array();
-               $wanted_headers = array();
-               $lines = preg_split("/[\n\r]+/", $section_text['EXPECTHEADERS']);
-               foreach ($lines as $line) {
-                       if (strpos($line, ':') !== false) {
-                               $line = explode(':', $line, 2);
-                               $want[trim($line[0])] = trim($line[1]);
-                               $wanted_headers[] = trim($line[0]) . ': ' . trim($line[1]);
-                       }
-               }
-               $output_headers = array();
-               foreach ($want as $k => $v) {
-                       if (isset($headers[$k])) {
-                               $output_headers[] = $k . ': ' . $headers[$k];
-                       }
-                       if (!isset($headers[$k]) || $headers[$k] != $v) {
-                               $failed_headers = true;
-                       }
-               }
-               ksort($wanted_headers);
-               $wanted_headers = implode("\n", $wanted_headers);
-               ksort($output_headers);
-               $output_headers = implode("\n", $output_headers);
-       }
-       show_file_block('out', $output);
-       if ($preload) {
-               $output = trim(preg_replace("/\n?Warning: Can't preload [^\n]*\n?/", "", $output));
-       }
-       if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) {
-               if (isset($section_text['EXPECTF'])) {
-                       $wanted = trim($section_text['EXPECTF']);
-               } else {
-                       $wanted = trim($section_text['EXPECTREGEX']);
-               }
-               show_file_block('exp', $wanted);
-               $wanted_re = preg_replace('/\r\n/', "\n", $wanted);
-               if (isset($section_text['EXPECTF'])) {
-                       // do preg_quote, but miss out any %r delimited sections
-                       $temp = "";
-                       $r = "%r";
-                       $startOffset = 0;
-                       $length = strlen($wanted_re);
-                       while ($startOffset < $length) {
-                               $start = strpos($wanted_re, $r, $startOffset);
-                               if ($start !== false) {
-                                       // we have found a start tag
-                                       $end = strpos($wanted_re, $r, $start + 2);
-                                       if ($end === false) {
-                                               // unbalanced tag, ignore it.
-                                               $end = $start = $length;
-                                       }
-                               } else {
-                                       // no more %r sections
-                                       $start = $end = $length;
-                               }
-                               // quote a non re portion of the string
-                               $temp .= preg_quote(substr($wanted_re, $startOffset, $start - $startOffset), '/');
-                               // add the re unquoted.
-                               if ($end > $start) {
-                                       $temp .= '(' . substr($wanted_re, $start + 2, $end - $start - 2) . ')';
-                               }
-                               $startOffset = $end + 2;
-                       }
-                       $wanted_re = $temp;
-                       // Stick to basics
-                       $wanted_re = str_replace('%e', '\\' . DIRECTORY_SEPARATOR, $wanted_re);
-                       $wanted_re = str_replace('%s', '[^\r\n]+', $wanted_re);
-                       $wanted_re = str_replace('%S', '[^\r\n]*', $wanted_re);
-                       $wanted_re = str_replace('%a', '.+', $wanted_re);
-                       $wanted_re = str_replace('%A', '.*', $wanted_re);
-                       $wanted_re = str_replace('%w', '\s*', $wanted_re);
-                       $wanted_re = str_replace('%i', '[+-]?\d+', $wanted_re);
-                       $wanted_re = str_replace('%d', '\d+', $wanted_re);
-                       $wanted_re = str_replace('%x', '[0-9a-fA-F]+', $wanted_re);
-                       $wanted_re = str_replace('%f', '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?', $wanted_re);
-                       $wanted_re = str_replace('%c', '.', $wanted_re);
-                       // %f allows two points "-.0.0" but that is the best *simple* expression
-               }
+     junit_start_timer($shortname);
+     $hrtime = hrtime();
+     $startTime = $hrtime[0] * 1000000000 + $hrtime[1];
+     $out = system_with_timeout($cmd, $env, $section_text['STDIN'] ?? null, $captureStdIn, $captureStdOut, $captureStdErr);
+     junit_finish_timer($shortname);
+     $hrtime = hrtime();
+     $time = $hrtime[0] * 1000000000 + $hrtime[1] - $startTime;
+     if ($time >= $slow_min_ms * 1000000) {
+         $PHP_FAILED_TESTS['SLOW'][] = array(
+             'name' => $file,
+             'test_name' => (is_array($IN_REDIRECT) ? $IN_REDIRECT['via'] : '') . $tested . " [$tested_file]",
+             'output' => '',
+             'diff' => '',
+             'info' => $time / 1000000000,
+         );
+     }
+     if (array_key_exists('CLEAN', $section_text) && (!$no_clean || $cfg['keep']['clean'])) {
+         if (trim($section_text['CLEAN'])) {
+             show_file_block('clean', $section_text['CLEAN']);
+             save_text($test_clean, trim($section_text['CLEAN']), $temp_clean);
+             if (!$no_clean) {
+                 $clean_params = array();
+                 settings2array($ini_overwrites, $clean_params);
+                 $clean_params = settings2params($clean_params);
 -                $extra = substr(PHP_OS, 0, 3) !== "WIN" ?
++                $extra = !IS_WINDOWS ?
+                     "unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;" : "";
+                 system_with_timeout("$extra $php $pass_options $extra_options -q $clean_params $no_file_cache \"$test_clean\"", $env);
+             }
+             if (!$cfg['keep']['clean']) {
+                 @unlink($test_clean);
+             }
+         }
+     }
+     @unlink($preload_filename);
+     $leaked = false;
+     $passed = false;
+     if ($valgrind) { // leak check
+         $leaked = filesize($memcheck_filename) > 0;
+         if (!$leaked) {
+             @unlink($memcheck_filename);
+         }
+     }
+     // Does the output match what is expected?
+     $output = preg_replace("/\r\n/", "\n", trim($out));
+     /* when using CGI, strip the headers from the output */
+     $headers = array();
+     if (!empty($uses_cgi) && preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $out, $match)) {
+         $output = trim($match[2]);
+         $rh = preg_split("/[\n\r]+/", $match[1]);
+         foreach ($rh as $line) {
+             if (strpos($line, ':') !== false) {
+                 $line = explode(':', $line, 2);
+                 $headers[trim($line[0])] = trim($line[1]);
+             }
+         }
+     }
+     $failed_headers = false;
+     if (isset($section_text['EXPECTHEADERS'])) {
+         $want = array();
+         $wanted_headers = array();
+         $lines = preg_split("/[\n\r]+/", $section_text['EXPECTHEADERS']);
+         foreach ($lines as $line) {
+             if (strpos($line, ':') !== false) {
+                 $line = explode(':', $line, 2);
+                 $want[trim($line[0])] = trim($line[1]);
+                 $wanted_headers[] = trim($line[0]) . ': ' . trim($line[1]);
+             }
+         }
+         $output_headers = array();
+         foreach ($want as $k => $v) {
+             if (isset($headers[$k])) {
+                 $output_headers[] = $k . ': ' . $headers[$k];
+             }
+             if (!isset($headers[$k]) || $headers[$k] != $v) {
+                 $failed_headers = true;
+             }
+         }
+         ksort($wanted_headers);
+         $wanted_headers = implode("\n", $wanted_headers);
+         ksort($output_headers);
+         $output_headers = implode("\n", $output_headers);
+     }
+     show_file_block('out', $output);
+     if ($preload) {
+         $output = trim(preg_replace("/\n?Warning: Can't preload [^\n]*\n?/", "", $output));
+     }
+     if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) {
+         if (isset($section_text['EXPECTF'])) {
+             $wanted = trim($section_text['EXPECTF']);
+         } else {
+             $wanted = trim($section_text['EXPECTREGEX']);
+         }
+         show_file_block('exp', $wanted);
+         $wanted_re = preg_replace('/\r\n/', "\n", $wanted);
+         if (isset($section_text['EXPECTF'])) {
+             // do preg_quote, but miss out any %r delimited sections
+             $temp = "";
+             $r = "%r";
+             $startOffset = 0;
+             $length = strlen($wanted_re);
+             while ($startOffset < $length) {
+                 $start = strpos($wanted_re, $r, $startOffset);
+                 if ($start !== false) {
+                     // we have found a start tag
+                     $end = strpos($wanted_re, $r, $start + 2);
+                     if ($end === false) {
+                         // unbalanced tag, ignore it.
+                         $end = $start = $length;
+                     }
+                 } else {
+                     // no more %r sections
+                     $start = $end = $length;
+                 }
+                 // quote a non re portion of the string
+                 $temp .= preg_quote(substr($wanted_re, $startOffset, $start - $startOffset), '/');
+                 // add the re unquoted.
+                 if ($end > $start) {
+                     $temp .= '(' . substr($wanted_re, $start + 2, $end - $start - 2) . ')';
+                 }
+                 $startOffset = $end + 2;
+             }
+             $wanted_re = $temp;
+             // Stick to basics
+             $wanted_re = str_replace('%e', '\\' . DIRECTORY_SEPARATOR, $wanted_re);
+             $wanted_re = str_replace('%s', '[^\r\n]+', $wanted_re);
+             $wanted_re = str_replace('%S', '[^\r\n]*', $wanted_re);
+             $wanted_re = str_replace('%a', '.+', $wanted_re);
+             $wanted_re = str_replace('%A', '.*', $wanted_re);
+             $wanted_re = str_replace('%w', '\s*', $wanted_re);
+             $wanted_re = str_replace('%i', '[+-]?\d+', $wanted_re);
+             $wanted_re = str_replace('%d', '\d+', $wanted_re);
+             $wanted_re = str_replace('%x', '[0-9a-fA-F]+', $wanted_re);
+             $wanted_re = str_replace('%f', '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?', $wanted_re);
+             $wanted_re = str_replace('%c', '.', $wanted_re);
+             // %f allows two points "-.0.0" but that is the best *simple* expression
+         }
  /* DEBUG YOUR REGEX HERE
-               var_dump($wanted_re);
-               print(str_repeat('=', 80) . "\n");
-               var_dump($output);
-                */
-               if (preg_match("/^$wanted_re\$/s", $output)) {
-                       $passed = true;
-                       if (!$cfg['keep']['php']) {
-                               @unlink($test_file);
-                       }
-                       @unlink($tmp_post);
-                       if (!$leaked && !$failed_headers) {
-                               if (isset($section_text['XFAIL'])) {
-                                       $warn = true;
-                                       $info = " (warn: XFAIL section but test passes)";
-                               } else if (isset($section_text['XLEAK'])) {
-                                       $warn = true;
-                                       $info = " (warn: XLEAK section but test passes)";
+         var_dump($wanted_re);
+         print(str_repeat('=', 80) . "\n");
+         var_dump($output);
+          */
+         if (preg_match("/^$wanted_re\$/s", $output)) {
+             $passed = true;
+             if (!$cfg['keep']['php']) {
+                 @unlink($test_file);
+             }
+             @unlink($tmp_post);
+             if (!$leaked && !$failed_headers) {
+                 if (isset($section_text['XFAIL'])) {
+                     $warn = true;
+                     $info = " (warn: XFAIL section but test passes)";
+                 } else if (isset($section_text['XLEAK'])) {
+                     $warn = true;
+                     $info = " (warn: XLEAK section but test passes)";
                  } else {
-                                       show_result("PASS", $tested, $tested_file, '', $temp_filenames);
-                                       junit_mark_test_as('PASS', $shortname, $tested);
-                                       return 'PASSED';
-                               }
-                       }
-               }
-       } else {
-               $wanted = trim($section_text['EXPECT']);
-               $wanted = preg_replace('/\r\n/', "\n", $wanted);
-               show_file_block('exp', $wanted);
-               // compare and leave on success
-               if (!strcmp($output, $wanted)) {
-                       $passed = true;
-                       if (!$cfg['keep']['php']) {
-                               @unlink($test_file);
-                       }
-                       @unlink($tmp_post);
-                       if (!$leaked && !$failed_headers) {
-                               if (isset($section_text['XFAIL'])) {
-                                       $warn = true;
-                                       $info = " (warn: XFAIL section but test passes)";
-                               } elseif (isset($section_text['XLEAK'])) {
-                                       $warn = true;
-                                       $info = " (warn: XLEAK section but test passes)";
+                     show_result("PASS", $tested, $tested_file, '', $temp_filenames);
+                     junit_mark_test_as('PASS', $shortname, $tested);
+                     return 'PASSED';
+                 }
+             }
+         }
+     } else {
+         $wanted = trim($section_text['EXPECT']);
+         $wanted = preg_replace('/\r\n/', "\n", $wanted);
+         show_file_block('exp', $wanted);
+         // compare and leave on success
+         if (!strcmp($output, $wanted)) {
+             $passed = true;
+             if (!$cfg['keep']['php']) {
+                 @unlink($test_file);
+             }
+             @unlink($tmp_post);
+             if (!$leaked && !$failed_headers) {
+                 if (isset($section_text['XFAIL'])) {
+                     $warn = true;
+                     $info = " (warn: XFAIL section but test passes)";
+                 } elseif (isset($section_text['XLEAK'])) {
+                     $warn = true;
+                     $info = " (warn: XLEAK section but test passes)";
                  } else {
-                                       show_result("PASS", $tested, $tested_file, '', $temp_filenames);
-                                       junit_mark_test_as('PASS', $shortname, $tested);
-                                       return 'PASSED';
-                               }
-                       }
-               }
-               $wanted_re = null;
-       }
-       // Test failed so we need to report details.
-       if ($failed_headers) {
-               $passed = false;
-               $wanted = $wanted_headers . "\n--HEADERS--\n" . $wanted;
-               $output = $output_headers . "\n--HEADERS--\n" . $output;
-               if (isset($wanted_re)) {
-                       $wanted_re = preg_quote($wanted_headers . "\n--HEADERS--\n", '/') . $wanted_re;
-               }
-       }
-       if ($leaked) {
+                     show_result("PASS", $tested, $tested_file, '', $temp_filenames);
+                     junit_mark_test_as('PASS', $shortname, $tested);
+                     return 'PASSED';
+                 }
+             }
+         }
+         $wanted_re = null;
+     }
+     // Test failed so we need to report details.
+     if ($failed_headers) {
+         $passed = false;
+         $wanted = $wanted_headers . "\n--HEADERS--\n" . $wanted;
+         $output = $output_headers . "\n--HEADERS--\n" . $output;
+         if (isset($wanted_re)) {
+             $wanted_re = preg_quote($wanted_headers . "\n--HEADERS--\n", '/') . $wanted_re;
+         }
+     }
+     if ($leaked) {
          $restype[] = isset($section_text['XLEAK']) ?
                          'XLEAK' : 'LEAK';
-       }
+     }
  
-       if ($warn) {
-               $restype[] = 'WARN';
-       }
+     if ($warn) {
+         $restype[] = 'WARN';
+     }
  
-       if (!$passed) {
-               if (isset($section_text['XFAIL'])) {
-                       $restype[] = 'XFAIL';
-                       $info = '  XFAIL REASON: ' . rtrim($section_text['XFAIL']);
-               } else if (isset($section_text['XLEAK'])) {
+     if (!$passed) {
+         if (isset($section_text['XFAIL'])) {
+             $restype[] = 'XFAIL';
+             $info = '  XFAIL REASON: ' . rtrim($section_text['XFAIL']);
+         } else if (isset($section_text['XLEAK'])) {
              $restype[] = 'XLEAK';
-                       $info = '  XLEAK REASON: ' . rtrim($section_text['XLEAK']);
+             $info = '  XLEAK REASON: ' . rtrim($section_text['XLEAK']);
          } else {
-                       $restype[] = 'FAIL';
-               }
-       }
-       if (!$passed) {
-               // write .exp
-               if (strpos($log_format, 'E') !== false && file_put_contents($exp_filename, $wanted, FILE_BINARY) === false) {
-                       error("Cannot create expected test output - $exp_filename");
-               }
-               // write .out
-               if (strpos($log_format, 'O') !== false && file_put_contents($output_filename, $output, FILE_BINARY) === false) {
-                       error("Cannot create test output - $output_filename");
-               }
-               // write .diff
-               $diff = generate_diff($wanted, $wanted_re, $output);
-               if (is_array($IN_REDIRECT)) {
-                       $orig_shortname = str_replace(TEST_PHP_SRCDIR . '/', '', $file);
-                       $diff = "# original source file: $orig_shortname\n" . $diff;
-               }
-               show_file_block('diff', $diff);
-               if (strpos($log_format, 'D') !== false && file_put_contents($diff_filename, $diff, FILE_BINARY) === false) {
-                       error("Cannot create test diff - $diff_filename");
-               }
-               // write .sh
-               if (strpos($log_format, 'S') !== false && file_put_contents($sh_filename, "#!/bin/sh
+             $restype[] = 'FAIL';
+         }
+     }
+     if (!$passed) {
+         // write .exp
+         if (strpos($log_format, 'E') !== false && file_put_contents($exp_filename, $wanted, FILE_BINARY) === false) {
+             error("Cannot create expected test output - $exp_filename");
+         }
+         // write .out
+         if (strpos($log_format, 'O') !== false && file_put_contents($output_filename, $output, FILE_BINARY) === false) {
+             error("Cannot create test output - $output_filename");
+         }
+         // write .diff
+         $diff = generate_diff($wanted, $wanted_re, $output);
+         if (is_array($IN_REDIRECT)) {
+             $orig_shortname = str_replace(TEST_PHP_SRCDIR . '/', '', $file);
+             $diff = "# original source file: $orig_shortname\n" . $diff;
+         }
+         show_file_block('diff', $diff);
+         if (strpos($log_format, 'D') !== false && file_put_contents($diff_filename, $diff, FILE_BINARY) === false) {
+             error("Cannot create test diff - $diff_filename");
+         }
+         // write .sh
+         if (strpos($log_format, 'S') !== false && file_put_contents($sh_filename, "#!/bin/sh
  
  {$cmd}
  ", FILE_BINARY) === false) {
@@@ -2953,32 -2936,32 +2953,32 @@@ function settings2array($settings, &$in
  
  function settings2params($ini_settings)
  {
-       $settings = '';
-       foreach($ini_settings as $name => $value) {
-               if (is_array($value)) {
-                       foreach($value as $val) {
-                               $val = addslashes($val);
-                               $settings .= " -d \"$name=$val\"";
-                       }
-               } else {
-                       if (IS_WINDOWS && !empty($value) && $value[0] == '"') {
-                               $len = strlen($value);
-                               if ($value[$len - 1] == '"') {
-                                       $value[0] = "'";
-                                       $value[$len - 1] = "'";
-                               }
-                       } else {
-                               $value = addslashes($value);
-                       }
-                       $settings .= " -d \"$name=$value\"";
-               }
-       }
-       return $settings;
+     $settings = '';
+     foreach($ini_settings as $name => $value) {
+         if (is_array($value)) {
+             foreach($value as $val) {
+                 $val = addslashes($val);
+                 $settings .= " -d \"$name=$val\"";
+             }
+         } else {
 -            if (substr(PHP_OS, 0, 3) == "WIN" && !empty($value) && $value[0] == '"') {
++            if (IS_WINDOWS && !empty($value) && $value[0] == '"') {
+                 $len = strlen($value);
+                 if ($value[$len - 1] == '"') {
+                     $value[0] = "'";
+                     $value[$len - 1] = "'";
+                 }
+             } else {
+                 $value = addslashes($value);
+             }
+             $settings .= " -d \"$name=$value\"";
+         }
+     }
+     return $settings;
  }
  
  function compute_summary()
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index c119530c03de29e5ade9633bb7d5019e3fd271af,d5fb9d1e7b682c4e29de696d2d6cfed37598d3db..be8b7a564293eafd3eb5e5be87de79fdec5325fd
@@@ -488,15 -488,15 +488,15 @@@ if (!is_dir($test_dir)) 
  }
  
  $dirs = array(
-       'ext',
-       'Sapi',
-       'Zend',
-       'tests'
+     'ext',
+     'Sapi',
+     'Zend',
+     'tests'
  );
  foreach ($dirs as $dir) {
-       copy_test_dir($dir, $test_dir);
+     copy_test_dir($dir, $test_dir);
  }
 -copy('run-tests.php', $test_dir . '/run-test.php');
 +copy('run-tests.php', $test_dir . '/run-tests.php');
  
  /* change this next line to true to use good-old
   * hand-assembled go-pear-bundle from the snapshot template */
diff --cc win32/ioutil.c
Simple merge
diff --cc win32/winutil.c
Simple merge