summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/bench.php74
-rw-r--r--Zend/micro_bench.php318
-rw-r--r--Zend/zend.c2
-rw-r--r--Zend/zend_execute.c2
-rwxr-xr-xZend/zend_vm_gen.php5522
-rwxr-xr-xext/ext_skel.php382
-rw-r--r--ext/ffi/ffi.stub.php4
-rwxr-xr-xext/fileinfo/create_data_file.php24
-rwxr-xr-xext/hash/bench.php136
-rw-r--r--ext/pdo_firebird/firebird_statement.c4
-rw-r--r--ext/pdo_firebird/pdo_firebird.c2
-rwxr-xr-xext/pdo_mysql/get_error_codes.php38
-rw-r--r--ext/pdo_sqlite/sqlite_statement.c2
-rwxr-xr-xext/phar/build_precommand.php62
-rw-r--r--ext/phar/makestub.php70
-rwxr-xr-xext/phar/phar/phar.php38
-rw-r--r--ext/phar/phar_object.stub.php6
-rw-r--r--ext/snmp/snmp.stub.php78
-rw-r--r--ext/zip/examples/addglob.php4
-rw-r--r--ext/zip/examples/create.php4
-rw-r--r--ext/zip/examples/dir.php4
-rw-r--r--ext/zip/examples/encryption.php6
-rw-r--r--ext/zip/examples/extract.php6
-rw-r--r--ext/zip/examples/extractAll.php6
-rw-r--r--ext/zip/examples/fopen.php8
-rw-r--r--ext/zip/examples/get_set_comments.php12
-rw-r--r--ext/zip/examples/odt.php22
-rw-r--r--ext/zip/examples/oldapi.php18
-rw-r--r--ext/zip/examples/set_compression.php2
-rw-r--r--main/php_variables.c2
-rwxr-xr-xrun-tests.php6210
-rwxr-xr-xsapi/cli/generate_mime_type_map.php46
-rwxr-xr-xsapi/phpdbg/create-test.php136
-rw-r--r--sapi/phpdbg/phpdbg_bp.c12
-rw-r--r--sapi/phpdbg/test.php68
-rwxr-xr-xscripts/dev/check_parameters.php538
-rwxr-xr-xscripts/dev/find_tested.php24
-rwxr-xr-xscripts/dev/search_underscores.php72
-rw-r--r--win32/build/mkdist.php800
-rw-r--r--win32/ioutil.c4
-rw-r--r--win32/winutil.c4
41 files changed, 7386 insertions, 7386 deletions
diff --git a/Zend/bench.php b/Zend/bench.php
index a6c0c6daed..8f84d64ee2 100644
--- a/Zend/bench.php
+++ b/Zend/bench.php
@@ -1,6 +1,6 @@
<?php
if (function_exists("date_default_timezone_set")) {
- date_default_timezone_set("UTC");
+ date_default_timezone_set("UTC");
}
function simple() {
@@ -220,30 +220,30 @@ function heapsort_r($n, &$ra) {
$ir = $n;
while (1) {
- if ($l > 1) {
- $rra = $ra[--$l];
- } else {
- $rra = $ra[$ir];
- $ra[$ir] = $ra[1];
- if (--$ir == 1) {
- $ra[1] = $rra;
- return;
- }
- }
- $i = $l;
- $j = $l << 1;
- while ($j <= $ir) {
- if (($j < $ir) && ($ra[$j] < $ra[$j+1])) {
- $j++;
- }
- if ($rra < $ra[$j]) {
- $ra[$i] = $ra[$j];
- $j += ($i = $j);
- } else {
- $j = $ir + 1;
- }
- }
- $ra[$i] = $rra;
+ if ($l > 1) {
+ $rra = $ra[--$l];
+ } else {
+ $rra = $ra[$ir];
+ $ra[$ir] = $ra[1];
+ if (--$ir == 1) {
+ $ra[1] = $rra;
+ return;
+ }
+ }
+ $i = $l;
+ $j = $l << 1;
+ while ($j <= $ir) {
+ if (($j < $ir) && ($ra[$j] < $ra[$j+1])) {
+ $j++;
+ }
+ if ($rra < $ra[$j]) {
+ $ra[$i] = $ra[$j];
+ $j += ($i = $j);
+ } else {
+ $j = $ir + 1;
+ }
+ }
+ $ra[$i] = $rra;
}
}
@@ -268,9 +268,9 @@ function mkmatrix ($rows, $cols) {
$count = 1;
$mx = array();
for ($i=0; $i<$rows; $i++) {
- for ($j=0; $j<$cols; $j++) {
- $mx[$i][$j] = $count++;
- }
+ for ($j=0; $j<$cols; $j++) {
+ $mx[$i][$j] = $count++;
+ }
}
return($mx);
}
@@ -278,13 +278,13 @@ function mkmatrix ($rows, $cols) {
function mmult ($rows, $cols, $m1, $m2) {
$m3 = array();
for ($i=0; $i<$rows; $i++) {
- for ($j=0; $j<$cols; $j++) {
- $x = 0;
- for ($k=0; $k<$cols; $k++) {
- $x += $m1[$i][$k] * $m2[$k][$j];
- }
- $m3[$i][$j] = $x;
- }
+ for ($j=0; $j<$cols; $j++) {
+ $x = 0;
+ for ($k=0; $k<$cols; $k++) {
+ $x += $m1[$i][$k] * $m2[$k][$j];
+ }
+ $m3[$i][$j] = $x;
+ }
}
return($m3);
}
@@ -353,7 +353,7 @@ function gethrtime()
function start_test()
{
- ob_start();
+ ob_start();
return gethrtime();
}
@@ -367,7 +367,7 @@ function end_test($start, $name)
$pad = str_repeat(" ", 24-strlen($name)-strlen($num));
echo $name.$pad.$num."\n";
- ob_start();
+ ob_start();
return gethrtime();
}
diff --git a/Zend/micro_bench.php b/Zend/micro_bench.php
index 42f1110c88..96ced487e1 100644
--- a/Zend/micro_bench.php
+++ b/Zend/micro_bench.php
@@ -22,220 +22,220 @@ function simpleicall($n) {
}
class Foo {
- static $a = 0;
- public $b = 0;
- const TEST = 0;
-
- static function read_static($n) {
- for ($i = 0; $i < $n; ++$i) {
- $x = self::$a;
- }
- }
-
- static function write_static($n) {
- for ($i = 0; $i < $n; ++$i) {
- self::$a = 0;
- }
- }
-
- static function isset_static($n) {
- for ($i = 0; $i < $n; ++$i) {
- $x = isset(self::$a);
- }
- }
-
- static function empty_static($n) {
- for ($i = 0; $i < $n; ++$i) {
- $x = empty(self::$a);
- }
- }
-
- static function f() {
- }
-
- static function call_static($n) {
- for ($i = 0; $i < $n; ++$i) {
- self::f();
- }
- }
-
- function read_prop($n) {
- for ($i = 0; $i < $n; ++$i) {
- $x = $this->b;
- }
- }
-
- function write_prop($n) {
- for ($i = 0; $i < $n; ++$i) {
- $this->b = 0;
- }
- }
-
- function assign_add_prop($n) {
- for ($i = 0; $i < $n; ++$i) {
- $this->b += 2;
- }
- }
-
- function pre_inc_prop($n) {
- for ($i = 0; $i < $n; ++$i) {
- ++$this->b;
- }
- }
-
- function pre_dec_prop($n) {
- for ($i = 0; $i < $n; ++$i) {
- --$this->b;
- }
- }
-
- function post_inc_prop($n) {
- for ($i = 0; $i < $n; ++$i) {
- $this->b++;
- }
- }
-
- function post_dec_prop($n) {
- for ($i = 0; $i < $n; ++$i) {
- $this->b--;
- }
- }
-
- function isset_prop($n) {
- for ($i = 0; $i < $n; ++$i) {
- $x = isset($this->b);
- }
- }
-
- function empty_prop($n) {
- for ($i = 0; $i < $n; ++$i) {
- $x = empty($this->b);
- }
- }
-
- function g() {
- }
-
- function call($n) {
- for ($i = 0; $i < $n; ++$i) {
- $this->g();
- }
- }
-
- function read_const($n) {
- for ($i = 0; $i < $n; ++$i) {
- $x = $this::TEST;
- }
- }
+ static $a = 0;
+ public $b = 0;
+ const TEST = 0;
+
+ static function read_static($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ $x = self::$a;
+ }
+ }
+
+ static function write_static($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ self::$a = 0;
+ }
+ }
+
+ static function isset_static($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ $x = isset(self::$a);
+ }
+ }
+
+ static function empty_static($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ $x = empty(self::$a);
+ }
+ }
+
+ static function f() {
+ }
+
+ static function call_static($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ self::f();
+ }
+ }
+
+ function read_prop($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ $x = $this->b;
+ }
+ }
+
+ function write_prop($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ $this->b = 0;
+ }
+ }
+
+ function assign_add_prop($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ $this->b += 2;
+ }
+ }
+
+ function pre_inc_prop($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ ++$this->b;
+ }
+ }
+
+ function pre_dec_prop($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ --$this->b;
+ }
+ }
+
+ function post_inc_prop($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ $this->b++;
+ }
+ }
+
+ function post_dec_prop($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ $this->b--;
+ }
+ }
+
+ function isset_prop($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ $x = isset($this->b);
+ }
+ }
+
+ function empty_prop($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ $x = empty($this->b);
+ }
+ }
+
+ function g() {
+ }
+
+ function call($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ $this->g();
+ }
+ }
+
+ function read_const($n) {
+ for ($i = 0; $i < $n; ++$i) {
+ $x = $this::TEST;
+ }
+ }
}
function read_static($n) {
- for ($i = 0; $i < $n; ++$i) {
- $x = Foo::$a;
- }
+ for ($i = 0; $i < $n; ++$i) {
+ $x = Foo::$a;
+ }
}
function write_static($n) {
- for ($i = 0; $i < $n; ++$i) {
- Foo::$a = 0;
- }
+ for ($i = 0; $i < $n; ++$i) {
+ Foo::$a = 0;
+ }
}
function isset_static($n) {
- for ($i = 0; $i < $n; ++$i) {
- $x = isset(Foo::$a);
- }
+ for ($i = 0; $i < $n; ++$i) {
+ $x = isset(Foo::$a);
+ }
}
function empty_static($n) {
- for ($i = 0; $i < $n; ++$i) {
- $x = empty(Foo::$a);
- }
+ for ($i = 0; $i < $n; ++$i) {
+ $x = empty(Foo::$a);
+ }
}
function call_static($n) {
- for ($i = 0; $i < $n; ++$i) {
- Foo::f();
- }
+ for ($i = 0; $i < $n; ++$i) {
+ Foo::f();
+ }
}
function create_object($n) {
- for ($i = 0; $i < $n; ++$i) {
- $x = new Foo();
- }
+ for ($i = 0; $i < $n; ++$i) {
+ $x = new Foo();
+ }
}
define('TEST', null);
function read_const($n) {
- for ($i = 0; $i < $n; ++$i) {
- $x = TEST;
- }
+ for ($i = 0; $i < $n; ++$i) {
+ $x = TEST;
+ }
}
function read_auto_global($n) {
- for ($i = 0; $i < $n; ++$i) {
- $x = $_GET;
- }
+ for ($i = 0; $i < $n; ++$i) {
+ $x = $_GET;
+ }
}
$g_var = 0;
function read_global_var($n) {
- for ($i = 0; $i < $n; ++$i) {
- $x = $GLOBALS['g_var'];
- }
+ for ($i = 0; $i < $n; ++$i) {
+ $x = $GLOBALS['g_var'];
+ }
}
function read_hash($n) {
- $hash = array('test' => 0);
- for ($i = 0; $i < $n; ++$i) {
- $x = $hash['test'];
- }
+ $hash = array('test' => 0);
+ for ($i = 0; $i < $n; ++$i) {
+ $x = $hash['test'];
+ }
}
function read_str_offset($n) {
- $str = "test";
- for ($i = 0; $i < $n; ++$i) {
- $x = $str[1];
- }
+ $str = "test";
+ for ($i = 0; $i < $n; ++$i) {
+ $x = $str[1];
+ }
}
function issetor($n) {
- $val = array(0,1,2,3,4,5,6,7,8,9);
- for ($i = 0; $i < $n; ++$i) {
- $x = $val ?: null;
- }
+ $val = array(0,1,2,3,4,5,6,7,8,9);
+ for ($i = 0; $i < $n; ++$i) {
+ $x = $val ?: null;
+ }
}
function issetor2($n) {
- $f = false; $j = 0;
- for ($i = 0; $i < $n; ++$i) {
- $x = $f ?: $j + 1;
- }
+ $f = false; $j = 0;
+ for ($i = 0; $i < $n; ++$i) {
+ $x = $f ?: $j + 1;
+ }
}
function ternary($n) {
- $val = array(0,1,2,3,4,5,6,7,8,9);
- $f = false;
- for ($i = 0; $i < $n; ++$i) {
- $x = $f ? null : $val;
- }
+ $val = array(0,1,2,3,4,5,6,7,8,9);
+ $f = false;
+ for ($i = 0; $i < $n; ++$i) {
+ $x = $f ? null : $val;
+ }
}
function ternary2($n) {
- $f = false; $j = 0;
- for ($i = 0; $i < $n; ++$i) {
- $x = $f ? $f : $j + 1;
- }
+ $f = false; $j = 0;
+ for ($i = 0; $i < $n; ++$i) {
+ $x = $f ? $f : $j + 1;
+ }
}
/*****/
function empty_loop($n) {
- for ($i = 0; $i < $n; ++$i) {
- }
+ for ($i = 0; $i < $n; ++$i) {
+ }
}
function gethrtime()
diff --git a/Zend/zend.c b/Zend/zend.c
index 20e7e85acc..9f3c05f973 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -962,7 +962,7 @@ void zend_register_standard_ini_entries(void) /* {{{ */
}
/* }}} */
-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);
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 9203fa6eb5..18fb8e9aba 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1597,7 +1597,7 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
string_len = Z_STRLEN_P(value);
c = (zend_uchar)Z_STRVAL_P(value)[0];
}
-
+
if (string_len != 1) {
if (string_len == 0) {
/* Error on empty input string */
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index ccf23613f7..7210bb2f20 100755
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -43,8 +43,8 @@ const HEADER_TEXT = <<< DATA
DATA;
/*
- This script creates zend_vm_execute.h and zend_vm_opcodes.h
- from existing zend_vm_def.h and zend_vm_execute.skl
+ This script creates zend_vm_execute.h and zend_vm_opcodes.h
+ from existing zend_vm_def.h and zend_vm_execute.skl
*/
error_reporting(E_ALL);
@@ -55,542 +55,542 @@ 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_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) {
- define($name, $val);
+ define($name, $val);
}
$vm_op_decode = array(
- "ANY" => 0,
- "CONST" => ZEND_VM_OP_SPEC | ZEND_VM_OP_CONST,
- "TMP" => ZEND_VM_OP_SPEC,
- "VAR" => ZEND_VM_OP_SPEC,
- "UNUSED" => ZEND_VM_OP_SPEC,
- "CV" => ZEND_VM_OP_SPEC,
- "TMPVAR" => ZEND_VM_OP_SPEC | ZEND_VM_OP_TMPVAR,
- "TMPVARCV" => ZEND_VM_OP_SPEC | ZEND_VM_OP_TMPVARCV,
- "NUM" => ZEND_VM_OP_NUM,
- "JMP_ADDR" => ZEND_VM_OP_JMP_ADDR,
- "TRY_CATCH" => ZEND_VM_OP_TRY_CATCH,
- "THIS" => ZEND_VM_OP_THIS,
- "NEXT" => ZEND_VM_OP_NEXT,
- "CLASS_FETCH" => ZEND_VM_OP_CLASS_FETCH,
- "CONSTRUCTOR" => ZEND_VM_OP_CONSTRUCTOR,
- "CONST_FETCH" => ZEND_VM_OP_CONST_FETCH,
- "CACHE_SLOT" => ZEND_VM_OP_CACHE_SLOT,
+ "ANY" => 0,
+ "CONST" => ZEND_VM_OP_SPEC | ZEND_VM_OP_CONST,
+ "TMP" => ZEND_VM_OP_SPEC,
+ "VAR" => ZEND_VM_OP_SPEC,
+ "UNUSED" => ZEND_VM_OP_SPEC,
+ "CV" => ZEND_VM_OP_SPEC,
+ "TMPVAR" => ZEND_VM_OP_SPEC | ZEND_VM_OP_TMPVAR,
+ "TMPVARCV" => ZEND_VM_OP_SPEC | ZEND_VM_OP_TMPVARCV,
+ "NUM" => ZEND_VM_OP_NUM,
+ "JMP_ADDR" => ZEND_VM_OP_JMP_ADDR,
+ "TRY_CATCH" => ZEND_VM_OP_TRY_CATCH,
+ "THIS" => ZEND_VM_OP_THIS,
+ "NEXT" => ZEND_VM_OP_NEXT,
+ "CLASS_FETCH" => ZEND_VM_OP_CLASS_FETCH,
+ "CONSTRUCTOR" => ZEND_VM_OP_CONSTRUCTOR,
+ "CONST_FETCH" => ZEND_VM_OP_CONST_FETCH,
+ "CACHE_SLOT" => ZEND_VM_OP_CACHE_SLOT,
);
$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_WRITE" => ZEND_VM_EXT_DIM_WRITE,
);
$vm_kind_name = array(
- ZEND_VM_KIND_CALL => "ZEND_VM_KIND_CALL",
- ZEND_VM_KIND_SWITCH => "ZEND_VM_KIND_SWITCH",
- ZEND_VM_KIND_GOTO => "ZEND_VM_KIND_GOTO",
- ZEND_VM_KIND_HYBRID => "ZEND_VM_KIND_HYBRID",
+ ZEND_VM_KIND_CALL => "ZEND_VM_KIND_CALL",
+ ZEND_VM_KIND_SWITCH => "ZEND_VM_KIND_SWITCH",
+ ZEND_VM_KIND_GOTO => "ZEND_VM_KIND_GOTO",
+ ZEND_VM_KIND_HYBRID => "ZEND_VM_KIND_HYBRID",
);
$op_types = array(
- "ANY",
- "CONST",
- "TMP",
- "VAR",
- "UNUSED",
- "CV"
+ "ANY",
+ "CONST",
+ "TMP",
+ "VAR",
+ "UNUSED",
+ "CV"
);
$op_types_ex = array(
- "ANY",
- "CONST",
- "TMPVARCV",
- "TMPVAR",
- "TMP",
- "VAR",
- "UNUSED",
- "CV",
+ "ANY",
+ "CONST",
+ "TMPVARCV",
+ "TMPVAR",
+ "TMP",
+ "VAR",
+ "UNUSED",
+ "CV",
);
$prefix = array(
- "ANY" => "",
- "TMP" => "_TMP",
- "VAR" => "_VAR",
- "CONST" => "_CONST",
- "UNUSED" => "_UNUSED",
- "CV" => "_CV",
- "TMPVAR" => "_TMPVAR",
- "TMPVARCV" => "_TMPVARCV",
+ "ANY" => "",
+ "TMP" => "_TMP",
+ "VAR" => "_VAR",
+ "CONST" => "_CONST",
+ "UNUSED" => "_UNUSED",
+ "CV" => "_CV",
+ "TMPVAR" => "_TMPVAR",
+ "TMPVARCV" => "_TMPVARCV",
);
$commutative_order = array(
- "ANY" => 0,
- "TMP" => 1,
- "VAR" => 2,
- "CONST" => 0,
- "UNUSED" => 0,
- "CV" => 4,
- "TMPVAR" => 2,
- "TMPVARCV" => 4,
+ "ANY" => 0,
+ "TMP" => 1,
+ "VAR" => 2,
+ "CONST" => 0,
+ "UNUSED" => 0,
+ "CV" => 4,
+ "TMPVAR" => 2,
+ "TMPVARCV" => 4,
);
$op1_type = array(
- "ANY" => "opline->op1_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->op1_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)",
);
$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_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, \\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" => "???",
);
$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, \\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" => "???",
);
$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, \\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" => "???",
);
$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, \\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" => "???",
);
$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, \\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, \\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, \\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)",
);
$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, \\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)",
);
$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, \\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" => "???",
);
$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, \\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" => "???",
);
$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, \\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" => "???",
);
$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, \\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" => "???",
);
$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, \\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)",
);
$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, \\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)",
);
$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, \\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, \\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, \\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" => "???",
);
$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, \\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" => "???",
);
$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, \\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" => "???",
);
$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, \\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" => "???",
);
$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(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" => "???",
);
$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(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" => "???",
);
$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(EX_VAR(opline->op1.var));}",
+ "TMP" => "",
+ "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(EX_VAR(opline->op2.var));}",
+ "TMP" => "",
+ "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 (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" => "???",
);
$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 (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" => "???",
);
$op1_free_unfetched = array(
- "ANY" => "FREE_UNFETCHED_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_UNFETCHED_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" => "???",
);
$op2_free_unfetched = array(
- "ANY" => "FREE_UNFETCHED_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_UNFETCHED_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" => "???",
);
$op_data_type = array(
- "ANY" => "(opline+1)->op1_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+1)->op1_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)",
);
$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)",
+ "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" => "???",
);
$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)",
+ "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, \\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" => "???",
);
$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((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" => "???",
);
$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 ((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" => "???",
);
$op_data_free_unfetched = array(
- "ANY" => "FREE_UNFETCHED_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_UNFETCHED_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" => "???",
);
$list = array(); // list of opcode handlers and helpers in original order
@@ -604,2484 +604,2484 @@ $used_extra_spec = array();
// Writes $s into resulting executor
function out($f, $s) {
- global $line_no;
+ global $line_no;
- fputs($f,$s);
- $line_no += substr_count($s, "\n");
+ fputs($f,$s);
+ $line_no += substr_count($s, "\n");
}
// Resets #line directives in resulting executor
function out_line($f) {
- global $line_no, $executor_file;
+ global $line_no, $executor_file;
- fputs($f,"#line ".($line_no+1)." \"".$executor_file."\"\n");
- ++$line_no;
+ fputs($f,"#line ".($line_no+1)." \"".$executor_file."\"\n");
+ ++$line_no;
}
function is_hot_helper($name) {
- global $helpers;
+ global $helpers;
- if (isset($helpers[$name]["hot"])) {
- return $helpers[$name]["hot"];
- } else {
- return false;
- }
+ if (isset($helpers[$name]["hot"])) {
+ return $helpers[$name]["hot"];
+ } else {
+ return false;
+ }
}
// Returns name of specialized helper
function helper_name($name, $spec, $op1, $op2, $extra_spec) {
- global $prefix, $helpers;
-
- $extra = "";
-
- if (isset($helpers[$name])) {
- // If we haven't helper with specified spicialized operands then
- // using unspecialized helper
- if (!isset($helpers[$name]["op1"][$op1])) {
- if (($op1 == 'TMP' || $op1 == 'VAR') &&
- isset($helpers[$name]["op1"]["TMPVAR"])) {
- $op1 = "TMPVAR";
- } else if (($op1 == 'TMP' || $op1 == 'VAR') &&
- isset($helpers[$name]["op1"]["TMPVARCV"])) {
- $op1 = "TMPVARCV";
- } else if ($op1 == 'CV' &&
- isset($helpers[$name]["op1"]["TMPVARCV"])) {
- $op1 = "TMPVARCV";
- } else if (isset($helpers[$name]["op1"]["ANY"])) {
- $op1 = "ANY";
- }
- }
- if (!isset($helpers[$name]["op2"][$op2])) {
- if (($op2 == 'TMP' || $op2 == 'VAR') &&
- isset($helpers[$name]["op2"]["TMPVAR"])) {
- $op2 = "TMPVAR";
- } else if (($op2 == 'TMP' || $op2 == 'VAR') &&
- isset($helpers[$name]["op2"]["TMPVARCV"])) {
- $op2 = "TMPVARCV";
- } else if ($op2 == 'CV' &&
- isset($helpers[$name]["op2"]["TMPVARCV"])) {
- $op2 = "TMPVARCV";
- } else if (isset($helpers[$name]["op2"]["ANY"])) {
- $op2 = "ANY";
- }
- }
- /* forward common specs (e.g. in ZEND_VM_DISPATCH_TO_HELPER) */
- if (isset($extra_spec, $helpers[$name]["spec"])) {
- $extra = extra_spec_name(array_intersect_key($extra_spec, $helpers[$name]["spec"]));
- }
- }
- return $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].$extra;
+ global $prefix, $helpers;
+
+ $extra = "";
+
+ if (isset($helpers[$name])) {
+ // If we haven't helper with specified spicialized operands then
+ // using unspecialized helper
+ if (!isset($helpers[$name]["op1"][$op1])) {
+ if (($op1 == 'TMP' || $op1 == 'VAR') &&
+ isset($helpers[$name]["op1"]["TMPVAR"])) {
+ $op1 = "TMPVAR";
+ } else if (($op1 == 'TMP' || $op1 == 'VAR') &&
+ isset($helpers[$name]["op1"]["TMPVARCV"])) {
+ $op1 = "TMPVARCV";
+ } else if ($op1 == 'CV' &&
+ isset($helpers[$name]["op1"]["TMPVARCV"])) {
+ $op1 = "TMPVARCV";
+ } else if (isset($helpers[$name]["op1"]["ANY"])) {
+ $op1 = "ANY";
+ }
+ }
+ if (!isset($helpers[$name]["op2"][$op2])) {
+ if (($op2 == 'TMP' || $op2 == 'VAR') &&
+ isset($helpers[$name]["op2"]["TMPVAR"])) {
+ $op2 = "TMPVAR";
+ } else if (($op2 == 'TMP' || $op2 == 'VAR') &&
+ isset($helpers[$name]["op2"]["TMPVARCV"])) {
+ $op2 = "TMPVARCV";
+ } else if ($op2 == 'CV' &&
+ isset($helpers[$name]["op2"]["TMPVARCV"])) {
+ $op2 = "TMPVARCV";
+ } else if (isset($helpers[$name]["op2"]["ANY"])) {
+ $op2 = "ANY";
+ }
+ }
+ /* forward common specs (e.g. in ZEND_VM_DISPATCH_TO_HELPER) */
+ if (isset($extra_spec, $helpers[$name]["spec"])) {
+ $extra = extra_spec_name(array_intersect_key($extra_spec, $helpers[$name]["spec"]));
+ }
+ }
+ return $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].$extra;
}
function opcode_name($name, $spec, $op1, $op2, $extra_spec) {
- global $prefix, $opnames, $opcodes;
-
- $extra = "";
-
- if (isset($opnames[$name])) {
- $opcode = $opcodes[$opnames[$name]];
- // If we haven't helper with specified spicialized operands then
- // using unspecialized helper
- if (!isset($opcode["op1"][$op1])) {
- if (($op1 == 'TMP' || $op1 == 'VAR') &&
- isset($opcode["op1"]["TMPVAR"])) {
- $op1 = "TMPVAR";
- } else if (($op1 == 'TMP' || $op1 == 'VAR') &&
- isset($opcode["op1"]["TMPVARCV"])) {
- $op1 = "TMPVARCV";
- } else if ($op1 == 'CV' &&
- isset($opcode["op1"]["TMPVARCV"])) {
- $op1 = "TMPVARCV";
- } else if (isset($opcode["op1"]["ANY"])) {
- $op1 = "ANY";
- } else if ($spec) {
- /* dispatch to invalid handler from unreachable code */
- return "ZEND_NULL";
- }
- }
- if (!isset($opcode["op2"][$op2])) {
- if (($op2 == 'TMP' || $op2 == 'VAR') &&
- isset($opcode["op2"]["TMPVAR"])) {
- $op2 = "TMPVAR";
- } else if (($op2 == 'TMP' || $op2 == 'VAR') &&
- isset($opcode["op2"]["TMPVARCV"])) {
- $op2 = "TMPVARCV";
- } else if ($op2 == 'CV' &&
- isset($opcode["op2"]["TMPVARCV"])) {
- $op2 = "TMPVARCV";
- } else if (isset($opcode["op2"]["ANY"])) {
- $op2 = "ANY";
- } else if ($spec) {
- /* dispatch to unknown handler in unreachable code */
- return "ZEND_NULL";
- }
- }
- /* forward common specs (e.g. in ZEND_VM_DISPATCH_TO_HANDLER) */
- if (isset($extra_spec, $opcode["spec"])) {
- $extra = extra_spec_name(array_intersect_key($extra_spec, $opcode["spec"]));
- }
- }
- return $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].$extra;
+ global $prefix, $opnames, $opcodes;
+
+ $extra = "";
+
+ if (isset($opnames[$name])) {
+ $opcode = $opcodes[$opnames[$name]];
+ // If we haven't helper with specified spicialized operands then
+ // using unspecialized helper
+ if (!isset($opcode["op1"][$op1])) {
+ if (($op1 == 'TMP' || $op1 == 'VAR') &&
+ isset($opcode["op1"]["TMPVAR"])) {
+ $op1 = "TMPVAR";
+ } else if (($op1 == 'TMP' || $op1 == 'VAR') &&
+ isset($opcode["op1"]["TMPVARCV"])) {
+ $op1 = "TMPVARCV";
+ } else if ($op1 == 'CV' &&
+ isset($opcode["op1"]["TMPVARCV"])) {
+ $op1 = "TMPVARCV";
+ } else if (isset($opcode["op1"]["ANY"])) {
+ $op1 = "ANY";
+ } else if ($spec) {
+ /* dispatch to invalid handler from unreachable code */
+ return "ZEND_NULL";
+ }
+ }
+ if (!isset($opcode["op2"][$op2])) {
+ if (($op2 == 'TMP' || $op2 == 'VAR') &&
+ isset($opcode["op2"]["TMPVAR"])) {
+ $op2 = "TMPVAR";
+ } else if (($op2 == 'TMP' || $op2 == 'VAR') &&
+ isset($opcode["op2"]["TMPVARCV"])) {
+ $op2 = "TMPVARCV";
+ } else if ($op2 == 'CV' &&
+ isset($opcode["op2"]["TMPVARCV"])) {
+ $op2 = "TMPVARCV";
+ } else if (isset($opcode["op2"]["ANY"])) {
+ $op2 = "ANY";
+ } else if ($spec) {
+ /* dispatch to unknown handler in unreachable code */
+ return "ZEND_NULL";
+ }
+ }
+ /* forward common specs (e.g. in ZEND_VM_DISPATCH_TO_HANDLER) */
+ if (isset($extra_spec, $opcode["spec"])) {
+ $extra = extra_spec_name(array_intersect_key($extra_spec, $opcode["spec"]));
+ }
+ }
+ return $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].$extra;
}
// Formats condition, protecting it by parentheses when needed.
function format_condition($condition) {
- if ($condition === "") {
- throw new InvalidArgumentException("A non empty string condition was expected.");
- }
+ if ($condition === "") {
+ throw new InvalidArgumentException("A non empty string condition was expected.");
+ }
- if ($condition[0] === "(" && substr($condition, -1) === ")") {
- return $condition;
- }
+ if ($condition[0] === "(" && substr($condition, -1) === ")") {
+ return $condition;
+ }
- return "(".$condition.")";
+ return "(".$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_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);
}
function skip_extra_spec_function($op1, $op2, $extra_spec) {
- global $commutative_order;
+ global $commutative_order;
- if (isset($extra_spec["NO_CONST_CONST"]) &&
- $op1 == "CONST" && $op2 == "CONST") {
- // Skip useless constant handlers
- return true;
- }
+ if (isset($extra_spec["NO_CONST_CONST"]) &&
+ $op1 == "CONST" && $op2 == "CONST") {
+ // Skip useless constant handlers
+ return true;
+ }
- if (isset($extra_spec["COMMUTATIVE"]) &&
- $commutative_order[$op1] < $commutative_order[$op2]) {
- // Skip duplicate commutative handlers
- return true;
- }
+ if (isset($extra_spec["COMMUTATIVE"]) &&
+ $commutative_order[$op1] < $commutative_order[$op2]) {
+ // Skip duplicate commutative handlers
+ return true;
+ }
- return false;
+ return false;
}
function is_hot_handler($hot, $op1, $op2, $extra_spec) {
- if (isset($extra_spec["SMART_BRANCH"]) && $extra_spec["SMART_BRANCH"] == 0) {
- return false;
- }
- if ($hot === 'HOT_' || $hot === 'INLINE_') {
- return true;
- } else if ($hot === 'HOT_NOCONST_') {
- return ($op1 !== 'CONST');
- } else if ($hot === 'HOT_NOCONSTCONST_') {
- return (($op1 !== 'CONST') || ($op2 !== 'CONST')) ;
- } else if ($hot === 'HOT_OBJ_') {
- return (($op1 === 'UNUSED') || ($op1 === 'CV')) && ($op2 === 'CONST');
- } else if ($hot === 'HOT_SEND_') {
- return !empty($extra_spec["QUICK_ARG"]);
- } else {
- return false;
- }
+ if (isset($extra_spec["SMART_BRANCH"]) && $extra_spec["SMART_BRANCH"] == 0) {
+ return false;
+ }
+ if ($hot === 'HOT_' || $hot === 'INLINE_') {
+ return true;
+ } else if ($hot === 'HOT_NOCONST_') {
+ return ($op1 !== 'CONST');
+ } else if ($hot === 'HOT_NOCONSTCONST_') {
+ return (($op1 !== 'CONST') || ($op2 !== 'CONST')) ;
+ } else if ($hot === 'HOT_OBJ_') {
+ return (($op1 === 'UNUSED') || ($op1 === 'CV')) && ($op2 === 'CONST');
+ } else if ($hot === 'HOT_SEND_') {
+ return !empty($extra_spec["QUICK_ARG"]);
+ } else {
+ return false;
+ }
}
function is_cold_handler($hot, $op1, $op2, $extra_spec) {
- if ($hot === 'COLD_') {
- return true;
- } else if ($hot === 'COLD_CONST_') {
- return ($op1 === 'CONST');
- } else if ($hot === 'COLD_CONSTCONST_') {
- return ($op1 === 'CONST' && $op2 === 'CONST');
- } else if ($hot === 'HOT_OBJ_') {
- return ($op1 === 'CONST');
- } else if ($hot === 'HOT_NOCONST_') {
- return ($op1 === 'CONST');
- } else if ($hot === 'HOT_NOCONSTCONST_') {
- return ($op1 === 'CONST' && $op2 === 'CONST');
- } else {
- return false;
- }
+ if ($hot === 'COLD_') {
+ return true;
+ } else if ($hot === 'COLD_CONST_') {
+ return ($op1 === 'CONST');
+ } else if ($hot === 'COLD_CONSTCONST_') {
+ return ($op1 === 'CONST' && $op2 === 'CONST');
+ } else if ($hot === 'HOT_OBJ_') {
+ return ($op1 === 'CONST');
+ } else if ($hot === 'HOT_NOCONST_') {
+ return ($op1 === 'CONST');
+ } else if ($hot === 'HOT_NOCONSTCONST_') {
+ return ($op1 === 'CONST' && $op2 === 'CONST');
+ } else {
+ return false;
+ }
}
function is_inline_hybrid_handler($name, $hot, $op1, $op2, $extra_spec) {
- return ($hot === 'INLINE_');
+ return ($hot === 'INLINE_');
}
// Generates opcode handler
function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno, $opcode, $extra_spec = null, &$switch_labels = array()) {
- global $definition_file, $prefix, $opnames, $gen_order;
-
- if (isset($opcode['alias']) && ($spec || $kind != ZEND_VM_KIND_SWITCH)) {
- return;
- }
-
- if ($spec && skip_extra_spec_function($op1, $op2, $extra_spec)) {
- return;
- }
-
- /* Skip SMART_BRANCH specialization for "cold" CONST_CONST instructions */
- if (isset($extra_spec["SMART_BRANCH"])) {
- if ($opcode["hot"] === 'HOT_NOCONSTCONST_'
- || $opcode["hot"] === 'COLD_CONSTCONST_') {
- if (($op1 === 'CONST') && ($op2 === 'CONST')) {
- if ($extra_spec["SMART_BRANCH"] == 0) {
- unset($extra_spec["SMART_BRANCH"]);
- } else {
- return;
- }
- }
- }
- }
-
- if (ZEND_VM_LINES) {
- out($f, "#line $lineno \"$definition_file\"\n");
- }
-
- // Generate opcode handler's entry point according to selected threading model
- $additional_func = false;
- $spec_name = $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].($spec?extra_spec_name($extra_spec):"");
- switch($kind) {
- case ZEND_VM_KIND_HYBRID:
- if (is_inline_hybrid_handler($name, $opcode["hot"], $op1, $op2, $extra_spec)) {
- $out = fopen('php://memory', 'w+');
- gen_code($out, $spec, $kind, 0, $code, $op1, $op2, $name, $extra_spec);
- rewind($out);
- $code =
- "\t\t\tHYBRID_CASE({$spec_name}):\n"
- . "\t\t\t\tVM_TRACE($spec_name)\n"
- . stream_get_contents($out);
- fclose($out);
- } else {
- $inline =
- isset($opcode["use"]) &&
- is_hot_handler($opcode["hot"], $op1, $op2, $extra_spec) ?
- "_INLINE" : "";
- $code =
- "\t\t\tHYBRID_CASE({$spec_name}):\n"
- . "\t\t\t\tVM_TRACE($spec_name)\n"
- . "\t\t\t\t{$spec_name}{$inline}_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n"
- . "\t\t\t\tHYBRID_BREAK();\n";
- }
- if (is_array($gen_order)) {
- $gen_order[$spec_name] = $code;
- } else {
- out($f, $code);
- }
- return;
- case ZEND_VM_KIND_CALL:
- if ($opcode["hot"] && ZEND_VM_KIND == ZEND_VM_KIND_HYBRID && is_hot_handler($opcode["hot"], $op1, $op2, $extra_spec)) {
- if (isset($opcode["use"])) {
- out($f,"static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
- $additional_func = true;
- } else {
- out($f,"static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
- }
- } else if ($opcode["hot"] && is_cold_handler($opcode["hot"], $op1, $op2, $extra_spec)) {
- out($f,"static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
- } else {
- out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
- }
- break;
- case ZEND_VM_KIND_SWITCH:
- if ($spec) {
- $cur = $switch_labels ? end($switch_labels) + 1 : 0;
- out($f,"case $cur: /* $spec_name */");
- $switch_labels[$spec_name] = $cur;
- } else {
- out($f,"case ".$name.":");
- }
- if ($use) {
- // This handler is used by other handlers. We will add label to call it.
- out($f," {$spec_name}_LABEL:\n");
- } else {
- out($f,"\n");
- }
- break;
- case ZEND_VM_KIND_GOTO:
- out($f,"{$spec_name}_LABEL: ZEND_VM_GUARD($spec_name);\n");
- break;
- }
-
- // Generate opcode handler's code
- gen_code($f, $spec, $kind, 0, $code, $op1, $op2, $name, $extra_spec);
-
- if ($additional_func) {
- out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
- out($f,"{\n");
- out($f,"\tZEND_VM_TAIL_CALL({$spec_name}_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
- out($f,"}\n");
- out($f,"\n");
- }
+ global $definition_file, $prefix, $opnames, $gen_order;
+
+ if (isset($opcode['alias']) && ($spec || $kind != ZEND_VM_KIND_SWITCH)) {
+ return;
+ }
+
+ if ($spec && skip_extra_spec_function($op1, $op2, $extra_spec)) {
+ return;
+ }
+
+ /* Skip SMART_BRANCH specialization for "cold" CONST_CONST instructions */
+ if (isset($extra_spec["SMART_BRANCH"])) {
+ if ($opcode["hot"] === 'HOT_NOCONSTCONST_'
+ || $opcode["hot"] === 'COLD_CONSTCONST_') {
+ if (($op1 === 'CONST') && ($op2 === 'CONST')) {
+ if ($extra_spec["SMART_BRANCH"] == 0) {
+ unset($extra_spec["SMART_BRANCH"]);
+ } else {
+ return;
+ }
+ }
+ }
+ }
+
+ if (ZEND_VM_LINES) {
+ out($f, "#line $lineno \"$definition_file\"\n");
+ }
+
+ // Generate opcode handler's entry point according to selected threading model
+ $additional_func = false;
+ $spec_name = $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].($spec?extra_spec_name($extra_spec):"");
+ switch($kind) {
+ case ZEND_VM_KIND_HYBRID:
+ if (is_inline_hybrid_handler($name, $opcode["hot"], $op1, $op2, $extra_spec)) {
+ $out = fopen('php://memory', 'w+');
+ gen_code($out, $spec, $kind, 0, $code, $op1, $op2, $name, $extra_spec);
+ rewind($out);
+ $code =
+ "\t\t\tHYBRID_CASE({$spec_name}):\n"
+ . "\t\t\t\tVM_TRACE($spec_name)\n"
+ . stream_get_contents($out);
+ fclose($out);
+ } else {
+ $inline =
+ isset($opcode["use"]) &&
+ is_hot_handler($opcode["hot"], $op1, $op2, $extra_spec) ?
+ "_INLINE" : "";
+ $code =
+ "\t\t\tHYBRID_CASE({$spec_name}):\n"
+ . "\t\t\t\tVM_TRACE($spec_name)\n"
+ . "\t\t\t\t{$spec_name}{$inline}_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n"
+ . "\t\t\t\tHYBRID_BREAK();\n";
+ }
+ if (is_array($gen_order)) {
+ $gen_order[$spec_name] = $code;
+ } else {
+ out($f, $code);
+ }
+ return;
+ case ZEND_VM_KIND_CALL:
+ if ($opcode["hot"] && ZEND_VM_KIND == ZEND_VM_KIND_HYBRID && is_hot_handler($opcode["hot"], $op1, $op2, $extra_spec)) {
+ if (isset($opcode["use"])) {
+ out($f,"static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+ $additional_func = true;
+ } else {
+ out($f,"static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+ }
+ } else if ($opcode["hot"] && is_cold_handler($opcode["hot"], $op1, $op2, $extra_spec)) {
+ out($f,"static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+ } else {
+ out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+ }
+ break;
+ case ZEND_VM_KIND_SWITCH:
+ if ($spec) {
+ $cur = $switch_labels ? end($switch_labels) + 1 : 0;
+ out($f,"case $cur: /* $spec_name */");
+ $switch_labels[$spec_name] = $cur;
+ } else {
+ out($f,"case ".$name.":");
+ }
+ if ($use) {
+ // This handler is used by other handlers. We will add label to call it.
+ out($f," {$spec_name}_LABEL:\n");
+ } else {
+ out($f,"\n");
+ }
+ break;
+ case ZEND_VM_KIND_GOTO:
+ out($f,"{$spec_name}_LABEL: ZEND_VM_GUARD($spec_name);\n");
+ break;
+ }
+
+ // Generate opcode handler's code
+ gen_code($f, $spec, $kind, 0, $code, $op1, $op2, $name, $extra_spec);
+
+ if ($additional_func) {
+ out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+ out($f,"{\n");
+ out($f,"\tZEND_VM_TAIL_CALL({$spec_name}_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
+ out($f,"}\n");
+ out($f,"\n");
+ }
}
// Generates helper
function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno, $inline, $cold = false, $hot = false, $extra_spec = null) {
- global $definition_file, $prefix;
-
- if ($kind == ZEND_VM_KIND_HYBRID && !$hot) {
- return;
- }
-
- if ($spec && skip_extra_spec_function($op1, $op2, $extra_spec)) {
- return;
- }
-
- if (ZEND_VM_LINES) {
- out($f, "#line $lineno \"$definition_file\"\n");
- }
-
- $spec_name = $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].($spec?extra_spec_name($extra_spec):"");
-
- // Generate helper's entry point according to selected threading model
- switch($kind) {
- case ZEND_VM_KIND_HYBRID:
- out($f, $spec_name . "_LABEL:\n");
- break;
- case ZEND_VM_KIND_CALL:
- if ($inline) {
- $zend_attributes = " zend_always_inline";
- $zend_fastcall = "";
- } else {
- if ($cold) {
- $zend_attributes = " zend_never_inline ZEND_COLD";
- } else {
- $zend_attributes = " zend_never_inline";
- }
- $zend_fastcall = " ZEND_FASTCALL";
- }
- if ($param == null) {
- // Helper without parameters
- out($f, "static$zend_attributes ZEND_OPCODE_HANDLER_RET$zend_fastcall $spec_name(ZEND_OPCODE_HANDLER_ARGS)\n");
- } else {
- // Helper with parameter
- out($f, "static$zend_attributes ZEND_OPCODE_HANDLER_RET$zend_fastcall $spec_name($param ZEND_OPCODE_HANDLER_ARGS_DC)\n");
- }
- break;
- case ZEND_VM_KIND_SWITCH:
- out($f, "$spec_name:\n");
- break;
- case ZEND_VM_KIND_GOTO:
- out($f, "$spec_name:\n");
- break;
- }
-
- // Generate helper's code
- gen_code($f, $spec, $kind, 0, $code, $op1, $op2, $name, $extra_spec);
+ global $definition_file, $prefix;
+
+ if ($kind == ZEND_VM_KIND_HYBRID && !$hot) {
+ return;
+ }
+
+ if ($spec && skip_extra_spec_function($op1, $op2, $extra_spec)) {
+ return;
+ }
+
+ if (ZEND_VM_LINES) {
+ out($f, "#line $lineno \"$definition_file\"\n");
+ }
+
+ $spec_name = $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].($spec?extra_spec_name($extra_spec):"");
+
+ // Generate helper's entry point according to selected threading model
+ switch($kind) {
+ case ZEND_VM_KIND_HYBRID:
+ out($f, $spec_name . "_LABEL:\n");
+ break;
+ case ZEND_VM_KIND_CALL:
+ if ($inline) {
+ $zend_attributes = " zend_always_inline";
+ $zend_fastcall = "";
+ } else {
+ if ($cold) {
+ $zend_attributes = " zend_never_inline ZEND_COLD";
+ } else {
+ $zend_attributes = " zend_never_inline";
+ }
+ $zend_fastcall = " ZEND_FASTCALL";
+ }
+ if ($param == null) {
+ // Helper without parameters
+ out($f, "static$zend_attributes ZEND_OPCODE_HANDLER_RET$zend_fastcall $spec_name(ZEND_OPCODE_HANDLER_ARGS)\n");
+ } else {
+ // Helper with parameter
+ out($f, "static$zend_attributes ZEND_OPCODE_HANDLER_RET$zend_fastcall $spec_name($param ZEND_OPCODE_HANDLER_ARGS_DC)\n");
+ }
+ break;
+ case ZEND_VM_KIND_SWITCH:
+ out($f, "$spec_name:\n");
+ break;
+ case ZEND_VM_KIND_GOTO:
+ out($f, "$spec_name:\n");
+ break;
+ }
+
+ // Generate helper's code
+ gen_code($f, $spec, $kind, 0, $code, $op1, $op2, $name, $extra_spec);
}
function gen_null_label($f, $kind, $prolog) {
- switch ($kind) {
- case ZEND_VM_KIND_CALL:
- out($f,$prolog."ZEND_NULL_HANDLER,\n");
- break;
- case ZEND_VM_KIND_SWITCH:
- out($f,$prolog."(void*)(uintptr_t)-1,\n");
- break;
- case ZEND_VM_KIND_GOTO:
- out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
- break;
- }
+ switch ($kind) {
+ case ZEND_VM_KIND_CALL:
+ out($f,$prolog."ZEND_NULL_HANDLER,\n");
+ break;
+ case ZEND_VM_KIND_SWITCH:
+ out($f,$prolog."(void*)(uintptr_t)-1,\n");
+ break;
+ case ZEND_VM_KIND_GOTO:
+ out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
+ break;
+ }
}
// Generates array of opcode handlers (specialized or unspecialized)
function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()) {
- global $opcodes, $opnames, $op_types, $prefix, $op_types_ex;
-
- $list = [];
- $next = 0;
- $label = 0;
- if ($spec) {
- // Emit labels for specialized executor
-
- // For each opcode in opcode number order
- foreach($opcodes as $num => $dsc) {
- if (isset($dsc['alias'])) {
- $specs[$num] = $specs[$opnames[$dsc['alias']]];
- continue;
- }
- $specs[$num] = "$label";
- $spec_op1 = $spec_op2 = $spec_extra = false;
- $def_op1_type = $def_op2_type = "ANY";
- $next = $num + 1;
- if (isset($dsc["op1"]) && !isset($dsc["op1"]["ANY"])) {
- $count = 0;
- foreach ($op_types_ex as $t) {
- if (isset($dsc["op1"][$t])) {
- $def_op1_type = $t;
- $count++;
- }
- }
- if ($count > 1) {
- $spec_op1 = true;
- $specs[$num] .= " | SPEC_RULE_OP1";
- $def_op1_type = "ANY";
- }
- }
- if (isset($dsc["op2"]) && !isset($dsc["op2"]["ANY"])) {
- $count = 0;
- foreach ($op_types_ex as $t) {
- if (isset($dsc["op2"][$t])) {
- $def_op2_type = $t;
- $count++;
- }
- }
- if ($count > 1) {
- $spec_op2 = true;
- $specs[$num] .= " | SPEC_RULE_OP2";
- $def_op2_type = "ANY";
- }
- }
- $spec_extra = call_user_func_array("array_merge", extra_spec_handler($dsc) ?: array(array()));
- $flags = extra_spec_flags($spec_extra);
- if ($flags) {
- $specs[$num] .= " | " . implode(" | ", $flags);
- }
- if ($num >= 256) {
- $opcodes[$num]['spec_code'] = $specs[$num];
- unset($specs[$num]);
- }
-
- $foreach_op1 = function($do) use ($dsc, $op_types) {
- return function($_, $op2) use ($do, $dsc, $op_types) {
- // For each op1.op_type except ANY
- foreach($op_types as $op1) {
- if ($op1 != "ANY") {
- if (!isset($dsc["op1"][$op1])) {
- if ($op1 == "TMP" || $op1 == "VAR") {
- if (isset($dsc["op1"]["TMPVAR"])) {
- $op1 = "TMPVAR";
- } else if (isset($dsc["op1"]["TMPVARCV"])) {
- $op1 = "TMPVARCV";
- } else {
- $op1 = "ANY";
- }
- } else if ($op1 == "CV" && isset($dsc["op1"]["TMPVARCV"])) {
- $op1 = "TMPVARCV";
- } else {
- // Try to use unspecialized handler
- $op1 = "ANY";
- }
- }
- $do($op1, $op2);
- }
- }
- };
- };
- $foreach_op2 = function($do) use ($dsc, $op_types) {
- return function($op1, $_) use ($do, $dsc, $op_types) {
- // For each op2.op_type except ANY
- foreach($op_types as $op2) {
- if ($op2 != "ANY") {
- if (!isset($dsc["op2"][$op2])) {
- if ($op2 == "TMP" || $op2 == "VAR") {
- if (isset($dsc["op2"]["TMPVAR"])) {
- $op2 = "TMPVAR";
- } else if (isset($dsc["op2"]["TMPVARCV"])) {
- $op2 = "TMPVARCV";
- } else {
- $op2 = "ANY";
- }
- } else if ($op2 == "CV" && isset($dsc["op2"]["TMPVARCV"])) {
- $op2 = "TMPVARCV";
- } else {
- // Try to use unspecialized handler
- $op2 = "ANY";
- }
- }
- $do($op1, $op2);
- }
- }
- };
- };
- $foreach_op_data = function($do) use ($dsc, $op_types) {
- return function($op1, $op2, $extra_spec = array()) use ($do, $dsc, $op_types) {
- // For each op_data.op_type except ANY
- foreach($op_types as $op_data) {
- if ($op_data != "ANY") {
- if (!isset($dsc["spec"]["OP_DATA"][$op_data])) {
- if ($op_data == "TMP" || $op_data == "VAR") {
- if (isset($dsc["spec"]["OP_DATA"]["TMPVAR"])) {
- $op_data = "TMPVAR";
- } else if (isset($dsc["spec"]["OP_DATA"]["TMPVARCV"])) {
- $op_data = "TMPVARCV";
- } else {
- // Try to use unspecialized handler
- $op_data = "ANY";
- }
- } else if ($op_data == "CV" && isset($dsc["OP_DATA"]["TMPVARCV"])) {
- $op_data = "TMPVARCV";
- } else {
- // Try to use unspecialized handler
- $op_data = "ANY";
- }
- }
- $do($op1, $op2, array("OP_DATA" => $op_data) + $extra_spec);
- }
- }
- };
- };
- $foreach_extra_spec = function($do, $spec) use ($dsc) {
- return function($op1, $op2, $extra_spec = array()) use ($do, $spec, $dsc) {
- foreach ($dsc["spec"][$spec] as $val) {
- $do($op1, $op2, array($spec => $val) + $extra_spec);
- }
- };
- };
- $generate = function ($op1, $op2, $extra_spec = array()) use ($f, $kind, $dsc, $prefix, $prolog, $num, $switch_labels, &$label, &$list) {
- global $commutative_order;
-
- // Check if specialized handler is defined
- /* TODO: figure out better way to signal "specialized and not defined" than an extra lookup */
- if (isset($dsc["op1"][$op1]) &&
- isset($dsc["op2"][$op2]) &&
- (!isset($extra_spec["OP_DATA"]) || isset($dsc["spec"]["OP_DATA"][$extra_spec["OP_DATA"]]))) {
- if (skip_extra_spec_function($op1, $op2, $extra_spec)) {
- gen_null_label($f, $kind, $prolog);
- $list[$label] = null;
- $label++;
- return;
- }
-
- /* Skip SMART_BRANCH specialization for "cold" CONST_CONST instructions */
- if (isset($extra_spec["SMART_BRANCH"])) {
- if ($dsc["hot"] === 'HOT_NOCONSTCONST_'
- || $dsc["hot"] === 'COLD_CONSTCONST_') {
- if (($op1 === 'CONST') && ($op2 === 'CONST')) {
- unset($extra_spec["SMART_BRANCH"]);
- }
- }
- }
-
- // Emit pointer to specialized handler
- $spec_name = $dsc["op"]."_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec);
- switch ($kind) {
- case ZEND_VM_KIND_CALL:
- out($f,"$prolog{$spec_name}_HANDLER,\n");
- break;
- case ZEND_VM_KIND_SWITCH:
- out($f,$prolog."(void*)(uintptr_t)$switch_labels[$spec_name],\n");
- break;
- case ZEND_VM_KIND_GOTO:
- out($f,$prolog."(void*)&&{$spec_name}_LABEL,\n");
- break;
- }
- $list[$label] = $spec_name;
- $label++;
- } else {
- // Emit pointer to handler of undefined opcode
- gen_null_label($f, $kind, $prolog);
- $list[$label] = null;
- $label++;
- }
- };
-
- $do = $generate;
- if ($spec_extra) {
- foreach ($spec_extra as $extra => $devnull) {
- if ($extra == "OP_DATA") {
- $do = $foreach_op_data($do);
- } else {
- $do = $foreach_extra_spec($do, $extra);
- }
- }
- }
- if ($spec_op2) {
- $do = $foreach_op2($do);
- }
- if ($spec_op1) {
- $do = $foreach_op1($do);
- }
-
- $do($def_op1_type, $def_op2_type);
- }
- } else {
- // Emit labels for unspecialized executor
-
- // For each opcode in opcode number order
- foreach($opcodes as $num => $dsc) {
- while ($next != $num) {
- // If some opcode numbers are not used then fill hole with pointers
- // to handler of undefined opcode
- switch ($kind) {
- case ZEND_VM_KIND_CALL:
- out($f,$prolog."ZEND_NULL_HANDLER,\n");
- break;
- case ZEND_VM_KIND_SWITCH:
- out($f,$prolog."(void*)(uintptr_t)-1,\n");
- break;
- case ZEND_VM_KIND_GOTO:
- out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
- break;
- }
- $next++;
- }
- if ($num >= 256) {
- continue;
- }
- $next = $num+1;
-
- if (isset($dsc['alias']) && $kind != ZEND_VM_KIND_SWITCH) {
- // Emit pointer to unspecialized handler
- switch ($kind) {
- case ZEND_VM_KIND_CALL:
- out($f,$prolog.$dsc['alias']."_HANDLER,\n");
- break;
- case ZEND_VM_KIND_GOTO:
- out($f,$prolog."(void*)&&".$dsc['alias']."_LABEL,\n");
- break;
- }
- $list[] = $dsc["op"];
- } else if ($dsc["code"]) { //ugly trick for ZEND_VM_DEFINE_OP
- // Emit pointer to unspecialized handler
- switch ($kind) {
- case ZEND_VM_KIND_CALL:
- out($f,$prolog.$dsc["op"]."_HANDLER,\n");
- break;
- case ZEND_VM_KIND_SWITCH:
- out($f,$prolog."(void*)(uintptr_t)".((string)$num).",\n");
- break;
- case ZEND_VM_KIND_GOTO:
- out($f,$prolog."(void*)&&".$dsc["op"]."_LABEL,\n");
- break;
- }
- $list[] = $dsc["op"];
- } else {
- switch ($kind) {
- case ZEND_VM_KIND_CALL:
- out($f,$prolog."ZEND_NULL_HANDLER,\n");
- break;
- case ZEND_VM_KIND_SWITCH:
- out($f,$prolog."(void*)(uintptr_t)-1,\n");
- break;
- case ZEND_VM_KIND_GOTO:
- out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
- break;
- }
- $list[] = null;
- }
- }
- }
-
- // Emit last handler's label (undefined opcode)
- switch ($kind) {
- case ZEND_VM_KIND_CALL:
- out($f,$prolog."ZEND_NULL_HANDLER\n");
- break;
- case ZEND_VM_KIND_SWITCH:
- out($f,$prolog."(void*)(uintptr_t)-1\n");
- break;
- case ZEND_VM_KIND_GOTO:
- out($f,$prolog."(void*)&&ZEND_NULL_LABEL\n");
- break;
- }
- $specs[$num + 1] = "$label";
-
- $l = fopen(__DIR__ . "/zend_vm_handlers.h", "w+") or die("ERROR: Cannot create zend_vm_handlers.h\n");
- out($l, "#define VM_HANDLERS(_) \\\n");
- foreach ($list as $n => $name) {
- if (!is_null($name)) {
- out($l, "\t_($n, $name) \\\n");
- }
- }
- out($l, "\t_($n+1, ZEND_NULL)\n");
- fclose($l);
+ global $opcodes, $opnames, $op_types, $prefix, $op_types_ex;
+
+ $list = [];
+ $next = 0;
+ $label = 0;
+ if ($spec) {
+ // Emit labels for specialized executor
+
+ // For each opcode in opcode number order
+ foreach($opcodes as $num => $dsc) {
+ if (isset($dsc['alias'])) {
+ $specs[$num] = $specs[$opnames[$dsc['alias']]];
+ continue;
+ }
+ $specs[$num] = "$label";
+ $spec_op1 = $spec_op2 = $spec_extra = false;
+ $def_op1_type = $def_op2_type = "ANY";
+ $next = $num + 1;
+ if (isset($dsc["op1"]) && !isset($dsc["op1"]["ANY"])) {
+ $count = 0;
+ foreach ($op_types_ex as $t) {
+ if (isset($dsc["op1"][$t])) {
+ $def_op1_type = $t;
+ $count++;
+ }
+ }
+ if ($count > 1) {
+ $spec_op1 = true;
+ $specs[$num] .= " | SPEC_RULE_OP1";
+ $def_op1_type = "ANY";
+ }
+ }
+ if (isset($dsc["op2"]) && !isset($dsc["op2"]["ANY"])) {
+ $count = 0;
+ foreach ($op_types_ex as $t) {
+ if (isset($dsc["op2"][$t])) {
+ $def_op2_type = $t;
+ $count++;
+ }
+ }
+ if ($count > 1) {
+ $spec_op2 = true;
+ $specs[$num] .= " | SPEC_RULE_OP2";
+ $def_op2_type = "ANY";
+ }
+ }
+ $spec_extra = call_user_func_array("array_merge", extra_spec_handler($dsc) ?: array(array()));
+ $flags = extra_spec_flags($spec_extra);
+ if ($flags) {
+ $specs[$num] .= " | " . implode(" | ", $flags);
+ }
+ if ($num >= 256) {
+ $opcodes[$num]['spec_code'] = $specs[$num];
+ unset($specs[$num]);
+ }
+
+ $foreach_op1 = function($do) use ($dsc, $op_types) {
+ return function($_, $op2) use ($do, $dsc, $op_types) {
+ // For each op1.op_type except ANY
+ foreach($op_types as $op1) {
+ if ($op1 != "ANY") {
+ if (!isset($dsc["op1"][$op1])) {
+ if ($op1 == "TMP" || $op1 == "VAR") {
+ if (isset($dsc["op1"]["TMPVAR"])) {
+ $op1 = "TMPVAR";
+ } else if (isset($dsc["op1"]["TMPVARCV"])) {
+ $op1 = "TMPVARCV";
+ } else {
+ $op1 = "ANY";
+ }
+ } else if ($op1 == "CV" && isset($dsc["op1"]["TMPVARCV"])) {
+ $op1 = "TMPVARCV";
+ } else {
+ // Try to use unspecialized handler
+ $op1 = "ANY";
+ }
+ }
+ $do($op1, $op2);
+ }
+ }
+ };
+ };
+ $foreach_op2 = function($do) use ($dsc, $op_types) {
+ return function($op1, $_) use ($do, $dsc, $op_types) {
+ // For each op2.op_type except ANY
+ foreach($op_types as $op2) {
+ if ($op2 != "ANY") {
+ if (!isset($dsc["op2"][$op2])) {
+ if ($op2 == "TMP" || $op2 == "VAR") {
+ if (isset($dsc["op2"]["TMPVAR"])) {
+ $op2 = "TMPVAR";
+ } else if (isset($dsc["op2"]["TMPVARCV"])) {
+ $op2 = "TMPVARCV";
+ } else {
+ $op2 = "ANY";
+ }
+ } else if ($op2 == "CV" && isset($dsc["op2"]["TMPVARCV"])) {
+ $op2 = "TMPVARCV";
+ } else {
+ // Try to use unspecialized handler
+ $op2 = "ANY";
+ }
+ }
+ $do($op1, $op2);
+ }
+ }
+ };
+ };
+ $foreach_op_data = function($do) use ($dsc, $op_types) {
+ return function($op1, $op2, $extra_spec = array()) use ($do, $dsc, $op_types) {
+ // For each op_data.op_type except ANY
+ foreach($op_types as $op_data) {
+ if ($op_data != "ANY") {
+ if (!isset($dsc["spec"]["OP_DATA"][$op_data])) {
+ if ($op_data == "TMP" || $op_data == "VAR") {
+ if (isset($dsc["spec"]["OP_DATA"]["TMPVAR"])) {
+ $op_data = "TMPVAR";
+ } else if (isset($dsc["spec"]["OP_DATA"]["TMPVARCV"])) {
+ $op_data = "TMPVARCV";
+ } else {
+ // Try to use unspecialized handler
+ $op_data = "ANY";
+ }
+ } else if ($op_data == "CV" && isset($dsc["OP_DATA"]["TMPVARCV"])) {
+ $op_data = "TMPVARCV";
+ } else {
+ // Try to use unspecialized handler
+ $op_data = "ANY";
+ }
+ }
+ $do($op1, $op2, array("OP_DATA" => $op_data) + $extra_spec);
+ }
+ }
+ };
+ };
+ $foreach_extra_spec = function($do, $spec) use ($dsc) {
+ return function($op1, $op2, $extra_spec = array()) use ($do, $spec, $dsc) {
+ foreach ($dsc["spec"][$spec] as $val) {
+ $do($op1, $op2, array($spec => $val) + $extra_spec);
+ }
+ };
+ };
+ $generate = function ($op1, $op2, $extra_spec = array()) use ($f, $kind, $dsc, $prefix, $prolog, $num, $switch_labels, &$label, &$list) {
+ global $commutative_order;
+
+ // Check if specialized handler is defined
+ /* TODO: figure out better way to signal "specialized and not defined" than an extra lookup */
+ if (isset($dsc["op1"][$op1]) &&
+ isset($dsc["op2"][$op2]) &&
+ (!isset($extra_spec["OP_DATA"]) || isset($dsc["spec"]["OP_DATA"][$extra_spec["OP_DATA"]]))) {
+ if (skip_extra_spec_function($op1, $op2, $extra_spec)) {
+ gen_null_label($f, $kind, $prolog);
+ $list[$label] = null;
+ $label++;
+ return;
+ }
+
+ /* Skip SMART_BRANCH specialization for "cold" CONST_CONST instructions */
+ if (isset($extra_spec["SMART_BRANCH"])) {
+ if ($dsc["hot"] === 'HOT_NOCONSTCONST_'
+ || $dsc["hot"] === 'COLD_CONSTCONST_') {
+ if (($op1 === 'CONST') && ($op2 === 'CONST')) {
+ unset($extra_spec["SMART_BRANCH"]);
+ }
+ }
+ }
+
+ // Emit pointer to specialized handler
+ $spec_name = $dsc["op"]."_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec);
+ switch ($kind) {
+ case ZEND_VM_KIND_CALL:
+ out($f,"$prolog{$spec_name}_HANDLER,\n");
+ break;
+ case ZEND_VM_KIND_SWITCH:
+ out($f,$prolog."(void*)(uintptr_t)$switch_labels[$spec_name],\n");
+ break;
+ case ZEND_VM_KIND_GOTO:
+ out($f,$prolog."(void*)&&{$spec_name}_LABEL,\n");
+ break;
+ }
+ $list[$label] = $spec_name;
+ $label++;
+ } else {
+ // Emit pointer to handler of undefined opcode
+ gen_null_label($f, $kind, $prolog);
+ $list[$label] = null;
+ $label++;
+ }
+ };
+
+ $do = $generate;
+ if ($spec_extra) {
+ foreach ($spec_extra as $extra => $devnull) {
+ if ($extra == "OP_DATA") {
+ $do = $foreach_op_data($do);
+ } else {
+ $do = $foreach_extra_spec($do, $extra);
+ }
+ }
+ }
+ if ($spec_op2) {
+ $do = $foreach_op2($do);
+ }
+ if ($spec_op1) {
+ $do = $foreach_op1($do);
+ }
+
+ $do($def_op1_type, $def_op2_type);
+ }
+ } else {
+ // Emit labels for unspecialized executor
+
+ // For each opcode in opcode number order
+ foreach($opcodes as $num => $dsc) {
+ while ($next != $num) {
+ // If some opcode numbers are not used then fill hole with pointers
+ // to handler of undefined opcode
+ switch ($kind) {
+ case ZEND_VM_KIND_CALL:
+ out($f,$prolog."ZEND_NULL_HANDLER,\n");
+ break;
+ case ZEND_VM_KIND_SWITCH:
+ out($f,$prolog."(void*)(uintptr_t)-1,\n");
+ break;
+ case ZEND_VM_KIND_GOTO:
+ out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
+ break;
+ }
+ $next++;
+ }
+ if ($num >= 256) {
+ continue;
+ }
+ $next = $num+1;
+
+ if (isset($dsc['alias']) && $kind != ZEND_VM_KIND_SWITCH) {
+ // Emit pointer to unspecialized handler
+ switch ($kind) {
+ case ZEND_VM_KIND_CALL:
+ out($f,$prolog.$dsc['alias']."_HANDLER,\n");
+ break;
+ case ZEND_VM_KIND_GOTO:
+ out($f,$prolog."(void*)&&".$dsc['alias']."_LABEL,\n");
+ break;
+ }
+ $list[] = $dsc["op"];
+ } else if ($dsc["code"]) { //ugly trick for ZEND_VM_DEFINE_OP
+ // Emit pointer to unspecialized handler
+ switch ($kind) {
+ case ZEND_VM_KIND_CALL:
+ out($f,$prolog.$dsc["op"]."_HANDLER,\n");
+ break;
+ case ZEND_VM_KIND_SWITCH:
+ out($f,$prolog."(void*)(uintptr_t)".((string)$num).",\n");
+ break;
+ case ZEND_VM_KIND_GOTO:
+ out($f,$prolog."(void*)&&".$dsc["op"]."_LABEL,\n");
+ break;
+ }
+ $list[] = $dsc["op"];
+ } else {
+ switch ($kind) {
+ case ZEND_VM_KIND_CALL:
+ out($f,$prolog."ZEND_NULL_HANDLER,\n");
+ break;
+ case ZEND_VM_KIND_SWITCH:
+ out($f,$prolog."(void*)(uintptr_t)-1,\n");
+ break;
+ case ZEND_VM_KIND_GOTO:
+ out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
+ break;
+ }
+ $list[] = null;
+ }
+ }
+ }
+
+ // Emit last handler's label (undefined opcode)
+ switch ($kind) {
+ case ZEND_VM_KIND_CALL:
+ out($f,$prolog."ZEND_NULL_HANDLER\n");
+ break;
+ case ZEND_VM_KIND_SWITCH:
+ out($f,$prolog."(void*)(uintptr_t)-1\n");
+ break;
+ case ZEND_VM_KIND_GOTO:
+ out($f,$prolog."(void*)&&ZEND_NULL_LABEL\n");
+ break;
+ }
+ $specs[$num + 1] = "$label";
+
+ $l = fopen(__DIR__ . "/zend_vm_handlers.h", "w+") or die("ERROR: Cannot create zend_vm_handlers.h\n");
+ out($l, "#define VM_HANDLERS(_) \\\n");
+ foreach ($list as $n => $name) {
+ if (!is_null($name)) {
+ out($l, "\t_($n, $name) \\\n");
+ }
+ }
+ out($l, "\t_($n+1, ZEND_NULL)\n");
+ fclose($l);
}
// Generates specialized offsets
function gen_specs($f, $prolog, $specs) {
- $lastdef = array_pop($specs);
- $last = 0;
- foreach ($specs as $num => $def) {
- while (++$last < $num) {
- out($f, "$prolog$lastdef,\n");
- }
- $last = $num;
- out($f, "$prolog$def,\n");
- }
- out($f, "$prolog$lastdef\n");
+ $lastdef = array_pop($specs);
+ $last = 0;
+ foreach ($specs as $num => $def) {
+ while (++$last < $num) {
+ out($f, "$prolog$lastdef,\n");
+ }
+ $last = $num;
+ out($f, "$prolog$def,\n");
+ }
+ out($f, "$prolog$lastdef\n");
}
// Generates handler for undefined opcodes (CALL threading model)
function gen_null_handler($f) {
- static $done = 0;
-
- // New and all executors with CALL threading model can use the same handler
- // for undefined opcodes, do we emit code for it only once
- if (!$done) {
- $done = 1;
- out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
- out($f,"{\n");
- out($f,"\tUSE_OPLINE\n");
- out($f,"\n");
- out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
- out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
- out($f,"}\n\n");
- }
+ static $done = 0;
+
+ // New and all executors with CALL threading model can use the same handler
+ // for undefined opcodes, do we emit code for it only once
+ if (!$done) {
+ $done = 1;
+ out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
+ out($f,"{\n");
+ out($f,"\tUSE_OPLINE\n");
+ out($f,"\n");
+ out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
+ out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
+ out($f,"}\n\n");
+ }
}
function extra_spec_name($extra_spec) {
- global $prefix;
-
- $s = "";
- if (isset($extra_spec["OP_DATA"])) {
- $s .= "_OP_DATA" . $prefix[$extra_spec["OP_DATA"]];
- }
- if (isset($extra_spec["RETVAL"])) {
- $s .= "_RETVAL_".($extra_spec["RETVAL"] ? "USED" : "UNUSED");
- }
- if (isset($extra_spec["QUICK_ARG"])) {
- if ($extra_spec["QUICK_ARG"]) {
- $s .= "_QUICK";
- }
- }
- if (isset($extra_spec["SMART_BRANCH"])) {
- if ($extra_spec["SMART_BRANCH"] == 1) {
- $s .= "_JMPZ";
- } else if ($extra_spec["SMART_BRANCH"] == 2) {
- $s .= "_JMPNZ";
- }
- }
- if (isset($extra_spec["ISSET"])) {
- if ($extra_spec["ISSET"] == 0) {
- $s .= "_SET";
- } else {
- $s .= "_EMPTY";
- }
- }
- return $s;
+ global $prefix;
+
+ $s = "";
+ if (isset($extra_spec["OP_DATA"])) {
+ $s .= "_OP_DATA" . $prefix[$extra_spec["OP_DATA"]];
+ }
+ if (isset($extra_spec["RETVAL"])) {
+ $s .= "_RETVAL_".($extra_spec["RETVAL"] ? "USED" : "UNUSED");
+ }
+ if (isset($extra_spec["QUICK_ARG"])) {
+ if ($extra_spec["QUICK_ARG"]) {
+ $s .= "_QUICK";
+ }
+ }
+ if (isset($extra_spec["SMART_BRANCH"])) {
+ if ($extra_spec["SMART_BRANCH"] == 1) {
+ $s .= "_JMPZ";
+ } else if ($extra_spec["SMART_BRANCH"] == 2) {
+ $s .= "_JMPNZ";
+ }
+ }
+ if (isset($extra_spec["ISSET"])) {
+ if ($extra_spec["ISSET"] == 0) {
+ $s .= "_SET";
+ } else {
+ $s .= "_EMPTY";
+ }
+ }
+ return $s;
}
function extra_spec_flags($extra_spec) {
- $s = array();
- if (isset($extra_spec["OP_DATA"])) {
- $s[] = "SPEC_RULE_OP_DATA";
- }
- if (isset($extra_spec["RETVAL"])) {
- $s[] = "SPEC_RULE_RETVAL";
- }
- if (isset($extra_spec["QUICK_ARG"])) {
- $s[] = "SPEC_RULE_QUICK_ARG";
- }
- if (isset($extra_spec["SMART_BRANCH"])) {
- $s[] = "SPEC_RULE_SMART_BRANCH";
- }
- if (isset($extra_spec["COMMUTATIVE"])) {
- $s[] = "SPEC_RULE_COMMUTATIVE";
- }
- if (isset($extra_spec["ISSET"])) {
- $s[] = "SPEC_RULE_ISSET";
- }
- return $s;
+ $s = array();
+ if (isset($extra_spec["OP_DATA"])) {
+ $s[] = "SPEC_RULE_OP_DATA";
+ }
+ if (isset($extra_spec["RETVAL"])) {
+ $s[] = "SPEC_RULE_RETVAL";
+ }
+ if (isset($extra_spec["QUICK_ARG"])) {
+ $s[] = "SPEC_RULE_QUICK_ARG";
+ }
+ if (isset($extra_spec["SMART_BRANCH"])) {
+ $s[] = "SPEC_RULE_SMART_BRANCH";
+ }
+ if (isset($extra_spec["COMMUTATIVE"])) {
+ $s[] = "SPEC_RULE_COMMUTATIVE";
+ }
+ if (isset($extra_spec["ISSET"])) {
+ $s[] = "SPEC_RULE_ISSET";
+ }
+ return $s;
}
function extra_spec_handler($dsc) {
- global $op_types_ex;
-
- if (!isset($dsc["spec"])) {
- return array(array());
- }
- $specs = $dsc["spec"];
-
- if (isset($specs["OP_DATA"])) {
- $op_data_specs = $specs["OP_DATA"];
- $specs["OP_DATA"] = array();
- foreach($op_types_ex as $op_data) {
- if (isset($dsc["spec"]["OP_DATA"][$op_data])) {
- $specs["OP_DATA"][] = $op_data;
- }
- }
- }
-
- $f = function($specs) use (&$f) {
- $spec = key($specs);
- $top = array_shift($specs);
- if ($specs) {
- $next = $f($specs);
- } else {
- $next = array(array());
- }
- $ret = array();
- foreach ($next as $existing) {
- foreach ($top as $mode) {
- $ret[] = array($spec => $mode) + $existing;
- }
- }
- return $ret;
- };
- return $f($specs);
+ global $op_types_ex;
+
+ if (!isset($dsc["spec"])) {
+ return array(array());
+ }
+ $specs = $dsc["spec"];
+
+ if (isset($specs["OP_DATA"])) {
+ $op_data_specs = $specs["OP_DATA"];
+ $specs["OP_DATA"] = array();
+ foreach($op_types_ex as $op_data) {
+ if (isset($dsc["spec"]["OP_DATA"][$op_data])) {
+ $specs["OP_DATA"][] = $op_data;
+ }
+ }
+ }
+
+ $f = function($specs) use (&$f) {
+ $spec = key($specs);
+ $top = array_shift($specs);
+ if ($specs) {
+ $next = $f($specs);
+ } else {
+ $next = array(array());
+ }
+ $ret = array();
+ foreach ($next as $existing) {
+ foreach ($top as $mode) {
+ $ret[] = array($spec => $mode) + $existing;
+ }
+ }
+ return $ret;
+ };
+ return $f($specs);
}
function read_order_file($fn) {
- $f = fopen($fn, "r");
- if (!is_resource($f)) {
- return false;
- }
- $order = [];
- while (!feof($f)) {
- $op = trim(fgets($f));
- if ($op !== "") {
- $order[$op] = null;
- }
- }
- fclose($f);
- return $order;
+ $f = fopen($fn, "r");
+ if (!is_resource($f)) {
+ return false;
+ }
+ $order = [];
+ while (!feof($f)) {
+ $op = trim(fgets($f));
+ if ($op !== "") {
+ $order[$op] = null;
+ }
+ }
+ fclose($f);
+ return $order;
}
// Generates all opcode handlers and helpers (specialized or unspecilaized)
function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array()) {
- global $list, $opcodes, $helpers, $op_types_ex, $gen_order;
-
- if ($kind == ZEND_VM_KIND_HYBRID && file_exists(__DIR__ . "/zend_vm_order.txt")) {
- $gen_order = read_order_file(__DIR__ . "/zend_vm_order.txt");
- } else {
- $gen_order = null;
- }
-
- if ($spec) {
- // Produce specialized executor
- $op1t = $op_types_ex;
- // for each op1.op_type
- foreach($op1t as $op1) {
- $op2t = $op_types_ex;
- // for each op2.op_type
- foreach($op2t as $op2) {
- // for each handlers in helpers in original order
- foreach ($list as $lineno => $dsc) {
- if (isset($dsc["handler"])) {
- $num = $dsc["handler"];
- foreach (extra_spec_handler($opcodes[$num]) as $extra_spec) {
- // Check if handler accepts such types of operands (op1 and op2)
- if (isset($opcodes[$num]["op1"][$op1]) &&
- isset($opcodes[$num]["op2"][$op2])) {
- // Generate handler code
- gen_handler($f, 1, $kind, $opcodes[$num]["op"], $op1, $op2, isset($opcodes[$num]["use"]), $opcodes[$num]["code"], $lineno, $opcodes[$num], $extra_spec, $switch_labels);
- }
- }
- } else if (isset($dsc["helper"])) {
- $num = $dsc["helper"];
- foreach (extra_spec_handler($helpers[$num]) as $extra_spec) {
- // Check if handler accepts such types of operands (op1 and op2)
- if (isset($helpers[$num]["op1"][$op1]) &&
- isset($helpers[$num]["op2"][$op2])) {
- // Generate helper code
- gen_helper($f, 1, $kind, $num, $op1, $op2, $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"], $helpers[$num]["cold"], $helpers[$num]["hot"], $extra_spec);
- }
- }
- } else {
- var_dump($dsc);
- die("??? $kind:$num\n");
- }
- }
- }
- }
- } else {
- // Produce unspecialized executor
-
- // for each handlers in helpers in original order
- foreach ($list as $lineno => $dsc) {
- if (isset($dsc["handler"])) {
- $num = $dsc["handler"];
- // Generate handler code
- if ($num < 256) {
- gen_handler($f, 0, $kind, $opcodes[$num]["op"], "ANY", "ANY", isset($opcodes[$num]["use"]), $opcodes[$num]["code"], $lineno, $opcodes[$num]);
- }
- } else if (isset($dsc["helper"])) {
- $num = $dsc["helper"];
- // Generate helper code
- gen_helper($f, 0, $kind, $num, "ANY", "ANY", $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"], $helpers[$num]["cold"], $helpers[$num]["hot"]);
- } else {
- var_dump($dsc);
- die("??? $kind:$num\n");
- }
- }
- }
-
- if (is_array($gen_order)) {
- foreach ($gen_order as $txt) {
- if ($txt !== null) {
- out($f, $txt);
- }
- }
- }
-
- if (ZEND_VM_LINES) {
- // Reset #line directives
- out_line($f);
- }
-
- // Generate handler for undefined opcodes
- switch ($kind) {
- case ZEND_VM_KIND_CALL:
- gen_null_handler($f);
- break;
- case ZEND_VM_KIND_SWITCH:
- out($f,"default: ZEND_NULL_LABEL:\n");
- out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
- out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
- break;
- case ZEND_VM_KIND_GOTO:
- out($f,"ZEND_NULL_LABEL:\n");
- out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
- out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
- break;
- case ZEND_VM_KIND_HYBRID:
- out($f,"\t\t\tHYBRID_CASE(HYBRID_HALT):\n");
- out($f,"#ifdef ZEND_VM_FP_GLOBAL_REG\n");
- out($f,"\t\t\t\texecute_data = orig_execute_data;\n");
- out($f,"#endif\n");
- out($f,"#ifdef ZEND_VM_IP_GLOBAL_REG\n");
- out($f,"\t\t\t\topline = orig_opline;\n");
- out($f,"#endif\n");
- out($f,"\t\t\t\treturn;\n");
- out($f,"\t\t\tHYBRID_DEFAULT:\n");
- out($f,"\t\t\t\tVM_TRACE(ZEND_NULL)\n");
- out($f,"\t\t\t\tZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
- out($f,"\t\t\t\tHYBRID_BREAK(); /* Never reached */\n");
- break;
- }
+ global $list, $opcodes, $helpers, $op_types_ex, $gen_order;
+
+ if ($kind == ZEND_VM_KIND_HYBRID && file_exists(__DIR__ . "/zend_vm_order.txt")) {
+ $gen_order = read_order_file(__DIR__ . "/zend_vm_order.txt");
+ } else {
+ $gen_order = null;
+ }
+
+ if ($spec) {
+ // Produce specialized executor
+ $op1t = $op_types_ex;
+ // for each op1.op_type
+ foreach($op1t as $op1) {
+ $op2t = $op_types_ex;
+ // for each op2.op_type
+ foreach($op2t as $op2) {
+ // for each handlers in helpers in original order
+ foreach ($list as $lineno => $dsc) {
+ if (isset($dsc["handler"])) {
+ $num = $dsc["handler"];
+ foreach (extra_spec_handler($opcodes[$num]) as $extra_spec) {
+ // Check if handler accepts such types of operands (op1 and op2)
+ if (isset($opcodes[$num]["op1"][$op1]) &&
+ isset($opcodes[$num]["op2"][$op2])) {
+ // Generate handler code
+ gen_handler($f, 1, $kind, $opcodes[$num]["op"], $op1, $op2, isset($opcodes[$num]["use"]), $opcodes[$num]["code"], $lineno, $opcodes[$num], $extra_spec, $switch_labels);
+ }
+ }
+ } else if (isset($dsc["helper"])) {
+ $num = $dsc["helper"];
+ foreach (extra_spec_handler($helpers[$num]) as $extra_spec) {
+ // Check if handler accepts such types of operands (op1 and op2)
+ if (isset($helpers[$num]["op1"][$op1]) &&
+ isset($helpers[$num]["op2"][$op2])) {
+ // Generate helper code
+ gen_helper($f, 1, $kind, $num, $op1, $op2, $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"], $helpers[$num]["cold"], $helpers[$num]["hot"], $extra_spec);
+ }
+ }
+ } else {
+ var_dump($dsc);
+ die("??? $kind:$num\n");
+ }
+ }
+ }
+ }
+ } else {
+ // Produce unspecialized executor
+
+ // for each handlers in helpers in original order
+ foreach ($list as $lineno => $dsc) {
+ if (isset($dsc["handler"])) {
+ $num = $dsc["handler"];
+ // Generate handler code
+ if ($num < 256) {
+ gen_handler($f, 0, $kind, $opcodes[$num]["op"], "ANY", "ANY", isset($opcodes[$num]["use"]), $opcodes[$num]["code"], $lineno, $opcodes[$num]);
+ }
+ } else if (isset($dsc["helper"])) {
+ $num = $dsc["helper"];
+ // Generate helper code
+ gen_helper($f, 0, $kind, $num, "ANY", "ANY", $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"], $helpers[$num]["cold"], $helpers[$num]["hot"]);
+ } else {
+ var_dump($dsc);
+ die("??? $kind:$num\n");
+ }
+ }
+ }
+
+ if (is_array($gen_order)) {
+ foreach ($gen_order as $txt) {
+ if ($txt !== null) {
+ out($f, $txt);
+ }
+ }
+ }
+
+ if (ZEND_VM_LINES) {
+ // Reset #line directives
+ out_line($f);
+ }
+
+ // Generate handler for undefined opcodes
+ switch ($kind) {
+ case ZEND_VM_KIND_CALL:
+ gen_null_handler($f);
+ break;
+ case ZEND_VM_KIND_SWITCH:
+ out($f,"default: ZEND_NULL_LABEL:\n");
+ out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
+ out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
+ break;
+ case ZEND_VM_KIND_GOTO:
+ out($f,"ZEND_NULL_LABEL:\n");
+ out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
+ out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
+ break;
+ case ZEND_VM_KIND_HYBRID:
+ out($f,"\t\t\tHYBRID_CASE(HYBRID_HALT):\n");
+ out($f,"#ifdef ZEND_VM_FP_GLOBAL_REG\n");
+ out($f,"\t\t\t\texecute_data = orig_execute_data;\n");
+ out($f,"#endif\n");
+ out($f,"#ifdef ZEND_VM_IP_GLOBAL_REG\n");
+ out($f,"\t\t\t\topline = orig_opline;\n");
+ out($f,"#endif\n");
+ out($f,"\t\t\t\treturn;\n");
+ out($f,"\t\t\tHYBRID_DEFAULT:\n");
+ out($f,"\t\t\t\tVM_TRACE(ZEND_NULL)\n");
+ out($f,"\t\t\t\tZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
+ out($f,"\t\t\t\tHYBRID_BREAK(); /* Never reached */\n");
+ break;
+ }
}
function skip_blanks($f, $prolog, $epilog) {
- if (trim($prolog) != "" || trim($epilog) != "") {
- out($f, $prolog.$epilog);
- }
+ if (trim($prolog) != "" || trim($epilog) != "") {
+ out($f, $prolog.$epilog);
+ }
}
// Generates executor from skeleton file and definition (specialized or unspecialized)
function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) {
- global $params, $skeleton_file, $line_no;
-
- $switch_labels = array();
- $lineno = 0;
- foreach ($skl as $line) {
- // Skeleton file contains special markers in form %NAME% those are
- // substituted by custom code
- if (preg_match("/(.*)[{][%]([A-Z_]*)[%][}](.*)/", $line, $m)) {
- switch ($m[2]) {
- case "DEFINES":
- out($f,"#define SPEC_START_MASK 0x0000ffff\n");
- out($f,"#define SPEC_EXTRA_MASK 0xfffc0000\n");
- out($f,"#define SPEC_RULE_OP1 0x00010000\n");
- out($f,"#define SPEC_RULE_OP2 0x00020000\n");
- out($f,"#define SPEC_RULE_OP_DATA 0x00040000\n");
- out($f,"#define SPEC_RULE_RETVAL 0x00080000\n");
- out($f,"#define SPEC_RULE_QUICK_ARG 0x00100000\n");
- out($f,"#define SPEC_RULE_SMART_BRANCH 0x00200000\n");
- out($f,"#define SPEC_RULE_COMMUTATIVE 0x00800000\n");
- out($f,"#define SPEC_RULE_ISSET 0x01000000\n");
- out($f,"\n");
- out($f,"static const uint32_t *zend_spec_handlers;\n");
- out($f,"static const void * const *zend_opcode_handlers;\n");
- out($f,"static int zend_handlers_count;\n");
- if ($kind == ZEND_VM_KIND_HYBRID) {
- out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
- out($f,"static const void * const * zend_opcode_handler_funcs;\n");
- out($f,"static zend_op hybrid_halt_op;\n");
- out($f,"#endif\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,"#endif\n\n");
- if ($kind == ZEND_VM_KIND_HYBRID) {
- 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,"#else\n");
- out($f,"# define zend_vm_get_opcode_handler_func zend_vm_get_opcode_handler\n");
- out($f,"#endif\n\n");
- }
- out($f,"#ifndef VM_TRACE\n");
- out($f,"# define VM_TRACE(op)\n");
- out($f,"#endif\n");
- out($f,"#ifndef VM_TRACE_START\n");
- out($f,"# define VM_TRACE_START()\n");
- out($f,"#endif\n");
- out($f,"#ifndef VM_TRACE_END\n");
- out($f,"# define VM_TRACE_END()\n");
- out($f,"#endif\n");
- switch ($kind) {
- case ZEND_VM_KIND_HYBRID:
- out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
- out($f,"#define HYBRID_NEXT() goto *(void**)(OPLINE->handler)\n");
- out($f,"#define HYBRID_SWITCH() HYBRID_NEXT();\n");
- out($f,"#define HYBRID_CASE(op) op ## _LABEL\n");
- out($f,"#define HYBRID_BREAK() HYBRID_NEXT()\n");
- out($f,"#define HYBRID_DEFAULT ZEND_NULL_LABEL\n");
- out($f,"#endif\n");
- case ZEND_VM_KIND_CALL:
- out($f,"\n");
- out($f,"#ifdef ZEND_VM_FP_GLOBAL_REG\n");
- out($f,"# define ZEND_OPCODE_HANDLER_ARGS void\n");
- out($f,"# define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU\n");
- out($f,"# define ZEND_OPCODE_HANDLER_ARGS_DC\n");
- out($f,"# define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC\n");
- out($f,"#else\n");
- out($f,"# define ZEND_OPCODE_HANDLER_ARGS zend_execute_data *execute_data\n");
- out($f,"# define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU execute_data\n");
- out($f,"# define ZEND_OPCODE_HANDLER_ARGS_DC , ZEND_OPCODE_HANDLER_ARGS\n");
- out($f,"# define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU\n");
- out($f,"#endif\n");
- out($f,"\n");
- out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
- out($f,"# define ZEND_OPCODE_HANDLER_RET void\n");
- out($f,"# define ZEND_VM_TAIL_CALL(call) call; return\n");
- out($f,"# ifdef ZEND_VM_TAIL_CALL_DISPATCH\n");
- out($f,"# define ZEND_VM_CONTINUE() ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); return\n");
- out($f,"# else\n");
- out($f,"# define ZEND_VM_CONTINUE() return\n");
- out($f,"# endif\n");
- if ($kind == ZEND_VM_KIND_HYBRID) {
- out($f,"# if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
- out($f,"# define ZEND_VM_RETURN() opline = &hybrid_halt_op; return\n");
- out($f,"# define ZEND_VM_HOT zend_always_inline ZEND_COLD ZEND_OPT_SIZE\n");
- out($f,"# define ZEND_VM_COLD ZEND_COLD ZEND_OPT_SIZE\n");
- out($f,"# else\n");
- out($f,"# define ZEND_VM_RETURN() opline = NULL; return\n");
- out($f,"# define ZEND_VM_HOT\n");
- out($f,"# define ZEND_VM_COLD ZEND_COLD ZEND_OPT_SIZE\n");
- out($f,"# endif\n");
- } else {
- out($f,"# define ZEND_VM_RETURN() opline = NULL; return\n");
- out($f,"# define ZEND_VM_COLD ZEND_COLD ZEND_OPT_SIZE\n");
- }
- out($f,"#else\n");
- out($f,"# define ZEND_OPCODE_HANDLER_RET int\n");
- out($f,"# define ZEND_VM_TAIL_CALL(call) return call\n");
- out($f,"# define ZEND_VM_CONTINUE() return 0\n");
- out($f,"# define ZEND_VM_RETURN() return -1\n");
- if ($kind == ZEND_VM_KIND_HYBRID) {
- out($f,"# define ZEND_VM_HOT\n");
- }
- out($f,"# define ZEND_VM_COLD ZEND_COLD ZEND_OPT_SIZE\n");
- out($f,"#endif\n");
- out($f,"\n");
- out($f,"typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS);\n");
- out($f,"\n");
- 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 SAVE_OPLINE\n");
- out($f,"#undef SAVE_OPLINE_EX\n");
- out($f,"#define DCL_OPLINE\n");
- out($f,"#ifdef ZEND_VM_IP_GLOBAL_REG\n");
- out($f,"# define OPLINE opline\n");
- out($f,"# define USE_OPLINE\n");
- out($f,"# define LOAD_OPLINE() opline = EX(opline)\n");
- out($f,"# define LOAD_OPLINE_EX()\n");
- out($f,"# define LOAD_NEXT_OPLINE() opline = EX(opline) + 1\n");
- out($f,"# define SAVE_OPLINE() EX(opline) = opline\n");
- out($f,"# define SAVE_OPLINE_EX() SAVE_OPLINE()\n");
- out($f,"#else\n");
- out($f,"# define OPLINE EX(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,"#endif\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,"#if defined(ZEND_VM_FP_GLOBAL_REG)\n");
- out($f,"# define ZEND_VM_ENTER_EX() ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
- out($f,"# define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_ENTER_EX()\n");
- out($f,"# define ZEND_VM_LEAVE() ZEND_VM_CONTINUE()\n");
- out($f,"#elif defined(ZEND_VM_IP_GLOBAL_REG)\n");
- out($f,"# define ZEND_VM_ENTER_EX() return 1\n");
- out($f,"# define ZEND_VM_ENTER() opline = EG(current_execute_data)->opline; ZEND_VM_ENTER_EX()\n");
- out($f,"# define ZEND_VM_LEAVE() return 2\n");
- out($f,"#else\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,"#endif\n");
- out($f,"#define ZEND_VM_INTERRUPT() ZEND_VM_TAIL_CALL(zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
- out($f,"#define ZEND_VM_LOOP_INTERRUPT() zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
- if ($kind == ZEND_VM_KIND_HYBRID) {
- out($f,"#define ZEND_VM_DISPATCH(opcode, opline) ZEND_VM_TAIL_CALL(((opcode_handler_t)zend_vm_get_opcode_handler_func(opcode, opline))(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
- } else {
- out($f,"#define ZEND_VM_DISPATCH(opcode, opline) ZEND_VM_TAIL_CALL(((opcode_handler_t)zend_vm_get_opcode_handler(opcode, opline))(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
- }
- out($f,"\n");
- out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS);\n");
- out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);\n");
- out($f,"\n");
- break;
- case ZEND_VM_KIND_SWITCH:
- out($f,"\n");
- 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 opline\n");
- out($f,"#ifdef ZEND_VM_IP_GLOBAL_REG\n");
- out($f,"# define DCL_OPLINE register const zend_op *opline __asm__(ZEND_VM_IP_GLOBAL_REG);\n");
- out($f,"#else\n");
- out($f,"# define DCL_OPLINE const zend_op *opline;\n");
- out($f,"#endif\n");
- out($f,"#define USE_OPLINE\n");
- out($f,"#define LOAD_OPLINE() opline = EX(opline)\n");
- out($f,"# define LOAD_OPLINE_EX() LOAD_OPLINE()\n");
- out($f,"#define LOAD_NEXT_OPLINE() opline = EX(opline) + 1\n");
- out($f,"#define SAVE_OPLINE() EX(opline) = 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,"#define ZEND_VM_CONTINUE() goto zend_vm_continue\n");
- out($f,"#define ZEND_VM_RETURN() return\n");
- out($f,"#define ZEND_VM_ENTER_EX() ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
- out($f,"#define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_ENTER_EX()\n");
- out($f,"#define ZEND_VM_LEAVE() ZEND_VM_CONTINUE()\n");
- out($f,"#define ZEND_VM_INTERRUPT() goto zend_interrupt_helper".($spec?"_SPEC":"").";\n");
- out($f,"#define ZEND_VM_LOOP_INTERRUPT() goto zend_interrupt_helper".($spec?"_SPEC":"").";\n");
- out($f,"#define ZEND_VM_DISPATCH(opcode, opline) dispatch_handler = zend_vm_get_opcode_handler(opcode, opline); goto zend_vm_dispatch;\n");
- out($f,"\n");
- break;
- case ZEND_VM_KIND_GOTO:
- out($f,"\n");
- 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 opline\n");
- out($f,"#ifdef ZEND_VM_IP_GLOBAL_REG\n");
- out($f,"# define DCL_OPLINE register const zend_op *opline __asm__(ZEND_VM_IP_GLOBAL_REG);\n");
- out($f,"#else\n");
- out($f,"# define DCL_OPLINE const zend_op *opline;\n");
- out($f,"#endif\n");
- out($f,"#define USE_OPLINE\n");
- out($f,"#define LOAD_OPLINE() opline = EX(opline)\n");
- out($f,"#define LOAD_OPLINE_EX() LOAD_OPLINE()\n");
- out($f,"#define LOAD_NEXT_OPLINE() opline = EX(opline) + 1\n");
- out($f,"#define SAVE_OPLINE() EX(opline) = opline\n");
- out($f,"#define SAVE_OPLINE_EX()\n");
- out($f,"#undef HANDLE_EXCEPTION\n");
- out($f,"#undef HANDLE_EXCEPTION_LEAVE\n");
- if (ZEND_VM_SPEC) {
- out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_SPEC_LABEL\n");
- out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_SPEC_LABEL\n");
- } else {
- out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_LABEL\n");
- out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_LABEL\n");
- }
- out($f,"#define ZEND_VM_CONTINUE() goto *(void**)(OPLINE->handler)\n");
- out($f,"#define ZEND_VM_RETURN() return\n");
- out($f,"#define ZEND_VM_ENTER_EX() ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
- out($f,"#define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_ENTER_EX()\n");
- out($f,"#define ZEND_VM_LEAVE() ZEND_VM_CONTINUE()\n");
- out($f,"#define ZEND_VM_INTERRUPT() goto zend_interrupt_helper".($spec?"_SPEC":"").";\n");
- out($f,"#define ZEND_VM_LOOP_INTERRUPT() goto zend_interrupt_helper".($spec?"_SPEC":"").";\n");
- out($f,"#define ZEND_VM_DISPATCH(opcode, opline) goto *(void**)(zend_vm_get_opcode_handler(opcode, opline));\n");
- out($f,"\n");
- break;
- }
- if ($kind == ZEND_VM_KIND_HYBRID) {
- gen_executor_code($f, $spec, ZEND_VM_KIND_CALL, $m[1]);
- out($f,"\n");
- out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
- out($f,"# undef ZEND_VM_TAIL_CALL\n");
- out($f,"# undef ZEND_VM_CONTINUE\n");
- out($f,"# undef ZEND_VM_RETURN\n");
+ global $params, $skeleton_file, $line_no;
+
+ $switch_labels = array();
+ $lineno = 0;
+ foreach ($skl as $line) {
+ // Skeleton file contains special markers in form %NAME% those are
+ // substituted by custom code
+ if (preg_match("/(.*)[{][%]([A-Z_]*)[%][}](.*)/", $line, $m)) {
+ switch ($m[2]) {
+ case "DEFINES":
+ out($f,"#define SPEC_START_MASK 0x0000ffff\n");
+ out($f,"#define SPEC_EXTRA_MASK 0xfffc0000\n");
+ out($f,"#define SPEC_RULE_OP1 0x00010000\n");
+ out($f,"#define SPEC_RULE_OP2 0x00020000\n");
+ out($f,"#define SPEC_RULE_OP_DATA 0x00040000\n");
+ out($f,"#define SPEC_RULE_RETVAL 0x00080000\n");
+ out($f,"#define SPEC_RULE_QUICK_ARG 0x00100000\n");
+ out($f,"#define SPEC_RULE_SMART_BRANCH 0x00200000\n");
+ out($f,"#define SPEC_RULE_COMMUTATIVE 0x00800000\n");
+ out($f,"#define SPEC_RULE_ISSET 0x01000000\n");
+ out($f,"\n");
+ out($f,"static const uint32_t *zend_spec_handlers;\n");
+ out($f,"static const void * const *zend_opcode_handlers;\n");
+ out($f,"static int zend_handlers_count;\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ out($f,"static const void * const * zend_opcode_handler_funcs;\n");
+ out($f,"static zend_op hybrid_halt_op;\n");
+ out($f,"#endif\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,"#endif\n\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ 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,"#else\n");
+ out($f,"# define zend_vm_get_opcode_handler_func zend_vm_get_opcode_handler\n");
+ out($f,"#endif\n\n");
+ }
+ out($f,"#ifndef VM_TRACE\n");
+ out($f,"# define VM_TRACE(op)\n");
+ out($f,"#endif\n");
+ out($f,"#ifndef VM_TRACE_START\n");
+ out($f,"# define VM_TRACE_START()\n");
+ out($f,"#endif\n");
+ out($f,"#ifndef VM_TRACE_END\n");
+ out($f,"# define VM_TRACE_END()\n");
+ out($f,"#endif\n");
+ switch ($kind) {
+ case ZEND_VM_KIND_HYBRID:
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ out($f,"#define HYBRID_NEXT() goto *(void**)(OPLINE->handler)\n");
+ out($f,"#define HYBRID_SWITCH() HYBRID_NEXT();\n");
+ out($f,"#define HYBRID_CASE(op) op ## _LABEL\n");
+ out($f,"#define HYBRID_BREAK() HYBRID_NEXT()\n");
+ out($f,"#define HYBRID_DEFAULT ZEND_NULL_LABEL\n");
+ out($f,"#endif\n");
+ case ZEND_VM_KIND_CALL:
+ out($f,"\n");
+ out($f,"#ifdef ZEND_VM_FP_GLOBAL_REG\n");
+ out($f,"# define ZEND_OPCODE_HANDLER_ARGS void\n");
+ out($f,"# define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU\n");
+ out($f,"# define ZEND_OPCODE_HANDLER_ARGS_DC\n");
+ out($f,"# define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC\n");
+ out($f,"#else\n");
+ out($f,"# define ZEND_OPCODE_HANDLER_ARGS zend_execute_data *execute_data\n");
+ out($f,"# define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU execute_data\n");
+ out($f,"# define ZEND_OPCODE_HANDLER_ARGS_DC , ZEND_OPCODE_HANDLER_ARGS\n");
+ out($f,"# define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU\n");
+ out($f,"#endif\n");
+ out($f,"\n");
+ out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
+ out($f,"# define ZEND_OPCODE_HANDLER_RET void\n");
+ out($f,"# define ZEND_VM_TAIL_CALL(call) call; return\n");
+ out($f,"# ifdef ZEND_VM_TAIL_CALL_DISPATCH\n");
+ out($f,"# define ZEND_VM_CONTINUE() ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); return\n");
+ out($f,"# else\n");
+ out($f,"# define ZEND_VM_CONTINUE() return\n");
+ out($f,"# endif\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"# if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ out($f,"# define ZEND_VM_RETURN() opline = &hybrid_halt_op; return\n");
+ out($f,"# define ZEND_VM_HOT zend_always_inline ZEND_COLD ZEND_OPT_SIZE\n");
+ out($f,"# define ZEND_VM_COLD ZEND_COLD ZEND_OPT_SIZE\n");
+ out($f,"# else\n");
+ out($f,"# define ZEND_VM_RETURN() opline = NULL; return\n");
+ out($f,"# define ZEND_VM_HOT\n");
+ out($f,"# define ZEND_VM_COLD ZEND_COLD ZEND_OPT_SIZE\n");
+ out($f,"# endif\n");
+ } else {
+ out($f,"# define ZEND_VM_RETURN() opline = NULL; return\n");
+ out($f,"# define ZEND_VM_COLD ZEND_COLD ZEND_OPT_SIZE\n");
+ }
+ out($f,"#else\n");
+ out($f,"# define ZEND_OPCODE_HANDLER_RET int\n");
+ out($f,"# define ZEND_VM_TAIL_CALL(call) return call\n");
+ out($f,"# define ZEND_VM_CONTINUE() return 0\n");
+ out($f,"# define ZEND_VM_RETURN() return -1\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"# define ZEND_VM_HOT\n");
+ }
+ out($f,"# define ZEND_VM_COLD ZEND_COLD ZEND_OPT_SIZE\n");
+ out($f,"#endif\n");
+ out($f,"\n");
+ out($f,"typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_HANDLER_ARGS);\n");
+ out($f,"\n");
+ 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 SAVE_OPLINE\n");
+ out($f,"#undef SAVE_OPLINE_EX\n");
+ out($f,"#define DCL_OPLINE\n");
+ out($f,"#ifdef ZEND_VM_IP_GLOBAL_REG\n");
+ out($f,"# define OPLINE opline\n");
+ out($f,"# define USE_OPLINE\n");
+ out($f,"# define LOAD_OPLINE() opline = EX(opline)\n");
+ out($f,"# define LOAD_OPLINE_EX()\n");
+ out($f,"# define LOAD_NEXT_OPLINE() opline = EX(opline) + 1\n");
+ out($f,"# define SAVE_OPLINE() EX(opline) = opline\n");
+ out($f,"# define SAVE_OPLINE_EX() SAVE_OPLINE()\n");
+ out($f,"#else\n");
+ out($f,"# define OPLINE EX(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,"#endif\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,"#if defined(ZEND_VM_FP_GLOBAL_REG)\n");
+ out($f,"# define ZEND_VM_ENTER_EX() ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
+ out($f,"# define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_ENTER_EX()\n");
+ out($f,"# define ZEND_VM_LEAVE() ZEND_VM_CONTINUE()\n");
+ out($f,"#elif defined(ZEND_VM_IP_GLOBAL_REG)\n");
+ out($f,"# define ZEND_VM_ENTER_EX() return 1\n");
+ out($f,"# define ZEND_VM_ENTER() opline = EG(current_execute_data)->opline; ZEND_VM_ENTER_EX()\n");
+ out($f,"# define ZEND_VM_LEAVE() return 2\n");
+ out($f,"#else\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,"#endif\n");
+ out($f,"#define ZEND_VM_INTERRUPT() ZEND_VM_TAIL_CALL(zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
+ out($f,"#define ZEND_VM_LOOP_INTERRUPT() zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#define ZEND_VM_DISPATCH(opcode, opline) ZEND_VM_TAIL_CALL(((opcode_handler_t)zend_vm_get_opcode_handler_func(opcode, opline))(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
+ } else {
+ out($f,"#define ZEND_VM_DISPATCH(opcode, opline) ZEND_VM_TAIL_CALL(((opcode_handler_t)zend_vm_get_opcode_handler(opcode, opline))(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n");
+ }
+ out($f,"\n");
+ out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS);\n");
+ out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS);\n");
+ out($f,"\n");
+ break;
+ case ZEND_VM_KIND_SWITCH:
+ out($f,"\n");
+ 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 opline\n");
+ out($f,"#ifdef ZEND_VM_IP_GLOBAL_REG\n");
+ out($f,"# define DCL_OPLINE register const zend_op *opline __asm__(ZEND_VM_IP_GLOBAL_REG);\n");
+ out($f,"#else\n");
+ out($f,"# define DCL_OPLINE const zend_op *opline;\n");
+ out($f,"#endif\n");
+ out($f,"#define USE_OPLINE\n");
+ out($f,"#define LOAD_OPLINE() opline = EX(opline)\n");
+ out($f,"# define LOAD_OPLINE_EX() LOAD_OPLINE()\n");
+ out($f,"#define LOAD_NEXT_OPLINE() opline = EX(opline) + 1\n");
+ out($f,"#define SAVE_OPLINE() EX(opline) = 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,"#define ZEND_VM_CONTINUE() goto zend_vm_continue\n");
+ out($f,"#define ZEND_VM_RETURN() return\n");
+ out($f,"#define ZEND_VM_ENTER_EX() ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
+ out($f,"#define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_ENTER_EX()\n");
+ out($f,"#define ZEND_VM_LEAVE() ZEND_VM_CONTINUE()\n");
+ out($f,"#define ZEND_VM_INTERRUPT() goto zend_interrupt_helper".($spec?"_SPEC":"").";\n");
+ out($f,"#define ZEND_VM_LOOP_INTERRUPT() goto zend_interrupt_helper".($spec?"_SPEC":"").";\n");
+ out($f,"#define ZEND_VM_DISPATCH(opcode, opline) dispatch_handler = zend_vm_get_opcode_handler(opcode, opline); goto zend_vm_dispatch;\n");
+ out($f,"\n");
+ break;
+ case ZEND_VM_KIND_GOTO:
+ out($f,"\n");
+ 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 opline\n");
+ out($f,"#ifdef ZEND_VM_IP_GLOBAL_REG\n");
+ out($f,"# define DCL_OPLINE register const zend_op *opline __asm__(ZEND_VM_IP_GLOBAL_REG);\n");
+ out($f,"#else\n");
+ out($f,"# define DCL_OPLINE const zend_op *opline;\n");
+ out($f,"#endif\n");
+ out($f,"#define USE_OPLINE\n");
+ out($f,"#define LOAD_OPLINE() opline = EX(opline)\n");
+ out($f,"#define LOAD_OPLINE_EX() LOAD_OPLINE()\n");
+ out($f,"#define LOAD_NEXT_OPLINE() opline = EX(opline) + 1\n");
+ out($f,"#define SAVE_OPLINE() EX(opline) = opline\n");
+ out($f,"#define SAVE_OPLINE_EX()\n");
+ out($f,"#undef HANDLE_EXCEPTION\n");
+ out($f,"#undef HANDLE_EXCEPTION_LEAVE\n");
+ if (ZEND_VM_SPEC) {
+ out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_SPEC_LABEL\n");
+ out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_SPEC_LABEL\n");
+ } else {
+ out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_LABEL\n");
+ out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_LABEL\n");
+ }
+ out($f,"#define ZEND_VM_CONTINUE() goto *(void**)(OPLINE->handler)\n");
+ out($f,"#define ZEND_VM_RETURN() return\n");
+ out($f,"#define ZEND_VM_ENTER_EX() ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\n");
+ out($f,"#define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_ENTER_EX()\n");
+ out($f,"#define ZEND_VM_LEAVE() ZEND_VM_CONTINUE()\n");
+ out($f,"#define ZEND_VM_INTERRUPT() goto zend_interrupt_helper".($spec?"_SPEC":"").";\n");
+ out($f,"#define ZEND_VM_LOOP_INTERRUPT() goto zend_interrupt_helper".($spec?"_SPEC":"").";\n");
+ out($f,"#define ZEND_VM_DISPATCH(opcode, opline) goto *(void**)(zend_vm_get_opcode_handler(opcode, opline));\n");
+ out($f,"\n");
+ break;
+ }
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ gen_executor_code($f, $spec, ZEND_VM_KIND_CALL, $m[1]);
+ out($f,"\n");
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ out($f,"# undef ZEND_VM_TAIL_CALL\n");
+ out($f,"# undef ZEND_VM_CONTINUE\n");
+ out($f,"# undef ZEND_VM_RETURN\n");
// out($f,"# undef ZEND_VM_INTERRUPT\n");
- out($f,"\n");
- out($f,"# define ZEND_VM_TAIL_CALL(call) call; ZEND_VM_CONTINUE()\n");
- out($f,"# define ZEND_VM_CONTINUE() HYBRID_NEXT()\n");
- out($f,"# define ZEND_VM_RETURN() goto HYBRID_HALT_LABEL\n");
+ out($f,"\n");
+ out($f,"# define ZEND_VM_TAIL_CALL(call) call; ZEND_VM_CONTINUE()\n");
+ out($f,"# define ZEND_VM_CONTINUE() HYBRID_NEXT()\n");
+ out($f,"# define ZEND_VM_RETURN() goto HYBRID_HALT_LABEL\n");
// out($f,"# define ZEND_VM_INTERRUPT() goto zend_interrupt_helper_SPEC_LABEL\n");
- out($f,"#endif\n\n");
- }
- break;
- case "EXECUTOR_NAME":
- out($f, $m[1].$executor_name.$m[3]."\n");
- break;
- case "HELPER_VARS":
- if ($kind == ZEND_VM_KIND_SWITCH) {
- out($f,$m[1]."const void *dispatch_handler;\n");
- }
- if ($kind != ZEND_VM_KIND_CALL && count($params)) {
- if ($kind == ZEND_VM_KIND_HYBRID) {
- out($f, "#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
- }
- // Emit local variables those are used for helpers' parameters
- foreach ($params as $param => $x) {
- out($f,$m[1].$param.";\n");
- }
- if ($kind == ZEND_VM_KIND_HYBRID) {
- out($f, "#endif\n");
- }
- }
- if ($kind != ZEND_VM_KIND_CALL && $kind != ZEND_VM_KIND_HYBRID) {
- out($f,"#ifdef ZEND_VM_FP_GLOBAL_REG\n");
- out($f,$m[1]."register zend_execute_data *execute_data __asm__(ZEND_VM_FP_GLOBAL_REG) = ex;\n");
- out($f,"#else\n");
- out($f,$m[1]."zend_execute_data *execute_data = ex;\n");
- out($f,"#endif\n");
- } else {
- out($f,"#ifdef ZEND_VM_IP_GLOBAL_REG\n");
- out($f,$m[1]."const zend_op *orig_opline = opline;\n");
- out($f,"#endif\n");
- out($f,"#ifdef ZEND_VM_FP_GLOBAL_REG\n");
- out($f,$m[1]."zend_execute_data *orig_execute_data = execute_data;\n");
- out($f,$m[1]."execute_data = ex;\n");
- out($f,"#else\n");
- out($f,$m[1]."zend_execute_data *execute_data = ex;\n");
- out($f,"#endif\n");
- }
- break;
- case "INTERNAL_LABELS":
- if ($kind == ZEND_VM_KIND_GOTO || $kind == ZEND_VM_KIND_HYBRID) {
- // Emit array of labels of opcode handlers and code for
- // zend_opcode_handlers initialization
- if ($kind == ZEND_VM_KIND_HYBRID) {
- out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
- }
- $prolog = $m[1];
- out($f,$prolog."if (UNEXPECTED(execute_data == NULL)) {\n");
- out($f,$prolog."\tstatic const void * const labels[] = {\n");
- gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_GOTO : $kind, $prolog."\t\t", $specs);
- out($f,$prolog."\t};\n");
- out($f,$prolog."\tzend_opcode_handlers = (const void **) labels;\n");
- out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(void*);\n");
- if ($kind == ZEND_VM_KIND_HYBRID) {
- out($f,$prolog."\tmemset(&hybrid_halt_op, 0, sizeof(hybrid_halt_op));\n");
- out($f,$prolog."\thybrid_halt_op.handler = (void*)&&HYBRID_HALT_LABEL;\n");
- out($f,$prolog."\tgoto HYBRID_HALT_LABEL;\n");
- } else {
- out($f,$prolog."\treturn;\n");
- }
- out($f,$prolog."}\n");
- if ($kind == ZEND_VM_KIND_HYBRID) {
- out($f,"#endif\n");
- }
- } else {
- skip_blanks($f, $m[1], $m[3]);
- }
- break;
- case "ZEND_VM_CONTINUE_LABEL":
- if ($kind == ZEND_VM_KIND_CALL || $kind == ZEND_VM_KIND_HYBRID) {
- // Only SWITCH dispatch method use it
- out($f,"#if !defined(ZEND_VM_FP_GLOBAL_REG) || !defined(ZEND_VM_IP_GLOBAL_REG)\n");
- out($f,$m[1]."\tint ret;".$m[3]."\n");
- out($f,"#endif\n");
- } else if ($kind == ZEND_VM_KIND_SWITCH) {
- // Only SWITCH dispatch method use it
- out($f,"zend_vm_continue:".$m[3]."\n");
- } else {
- skip_blanks($f, $m[1], $m[3]);
- }
- break;
- case "ZEND_VM_DISPATCH":
- // Emit code that dispatches to opcode handler
- switch ($kind) {
- case ZEND_VM_KIND_SWITCH:
- out($f, $m[1]."dispatch_handler = OPLINE->handler;\nzend_vm_dispatch:\n".$m[1]."switch ((int)(uintptr_t)dispatch_handler)".$m[3]."\n");
- break;
- case ZEND_VM_KIND_GOTO:
- out($f, $m[1]."goto *(void**)(OPLINE->handler);".$m[3]."\n");
- break;
- case ZEND_VM_KIND_HYBRID:
- out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
- out($f, $m[1]."HYBRID_SWITCH()".$m[3]."\n");
- out($f,"#else\n");
- case ZEND_VM_KIND_CALL:
- out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
- out($f, $m[1]."((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
- out($f, $m[1]."if (UNEXPECTED(!OPLINE))".$m[3]."\n");
- out($f,"#else\n");
- out($f, $m[1]."if (UNEXPECTED((ret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)) != 0))".$m[3]."\n");
- out($f,"#endif\n");
- if ($kind == ZEND_VM_KIND_HYBRID) {
- out($f,"#endif\n");
- }
- break;
- }
- break;
- case "INTERNAL_EXECUTOR":
- if ($kind != ZEND_VM_KIND_CALL) {
- // Emit executor code
- if ($kind == ZEND_VM_KIND_HYBRID) {
- out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
- }
- gen_executor_code($f, $spec, $kind, $m[1], $switch_labels);
- }
- if ($kind == ZEND_VM_KIND_CALL || $kind == ZEND_VM_KIND_HYBRID) {
- // Executor is defined as a set of functions
- if ($kind == ZEND_VM_KIND_HYBRID) {
- out($f,"#else\n");
- }
- out($f,
- "#ifdef ZEND_VM_FP_GLOBAL_REG\n" .
- $m[1]."execute_data = orig_execute_data;\n" .
- "# ifdef ZEND_VM_IP_GLOBAL_REG\n" .
- $m[1]."opline = orig_opline;\n" .
- "# endif\n" .
- $m[1]."return;\n" .
- "#else\n" .
- $m[1]."if (EXPECTED(ret > 0)) {\n" .
- $m[1]."\texecute_data = EG(current_execute_data);\n".
- $m[1]."\tZEND_VM_LOOP_INTERRUPT_CHECK();\n".
- $m[1]."} else {\n" .
- "# ifdef ZEND_VM_IP_GLOBAL_REG\n" .
- $m[1]."\topline = orig_opline;\n" .
- "# endif\n".
- $m[1]."\treturn;\n".
- $m[1]."}\n".
- "#endif\n");
- if ($kind == ZEND_VM_KIND_HYBRID) {
- out($f,"#endif\n");
- }
- }
- break;
- case "EXTERNAL_EXECUTOR":
- if ($kind == ZEND_VM_KIND_CALL) {
- gen_executor_code($f, $spec, $kind, $m[1]);
- }
- break;
- case "INITIALIZER_NAME":
- out($f, $m[1].$initializer_name.$m[3]."\n");
- break;
- case "EXTERNAL_LABELS":
- // Emit code that initializes zend_opcode_handlers array
- $prolog = $m[1];
- if ($kind == ZEND_VM_KIND_GOTO) {
- // Labels are defined in the executor itself, so we call it
- // with execute_data NULL and it sets zend_opcode_handlers array
- out($f,$prolog."static const uint32_t specs[] = {\n");
- gen_specs($f, $prolog."\t", $specs);
- out($f,$prolog."};\n");
- out($f,$prolog."zend_spec_handlers = specs;\n");
- out($f,$prolog.$executor_name."_ex(NULL);\n");
- } else {
- out($f,$prolog."static const void * const labels[] = {\n");
- gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_CALL : $kind, $prolog."\t", $specs, $switch_labels);
- out($f,$prolog."};\n");
- out($f,$prolog."static const uint32_t specs[] = {\n");
- gen_specs($f, $prolog."\t", $specs);
- out($f,$prolog."};\n");
- if ($kind == ZEND_VM_KIND_HYBRID) {
- out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
- out($f,$prolog."zend_opcode_handler_funcs = labels;\n");
- out($f,$prolog."zend_spec_handlers = specs;\n");
- out($f,$prolog.$executor_name."_ex(NULL);\n");
- out($f,"#else\n");
- }
- out($f,$prolog."zend_opcode_handlers = labels;\n");
- out($f,$prolog."zend_handlers_count = sizeof(labels) / sizeof(void*);\n");
- out($f,$prolog."zend_spec_handlers = specs;\n");
- if ($kind == ZEND_VM_KIND_HYBRID) {
- out($f,"#endif\n");
- }
- }
- break;
- default:
- die("ERROR: Unknown keyword ".$m[2]." in skeleton file.\n");
- }
- } else {
- // Copy the line as is
- out($f, $line);
- }
- }
+ out($f,"#endif\n\n");
+ }
+ break;
+ case "EXECUTOR_NAME":
+ out($f, $m[1].$executor_name.$m[3]."\n");
+ break;
+ case "HELPER_VARS":
+ if ($kind == ZEND_VM_KIND_SWITCH) {
+ out($f,$m[1]."const void *dispatch_handler;\n");
+ }
+ if ($kind != ZEND_VM_KIND_CALL && count($params)) {
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f, "#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ }
+ // Emit local variables those are used for helpers' parameters
+ foreach ($params as $param => $x) {
+ out($f,$m[1].$param.";\n");
+ }
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f, "#endif\n");
+ }
+ }
+ if ($kind != ZEND_VM_KIND_CALL && $kind != ZEND_VM_KIND_HYBRID) {
+ out($f,"#ifdef ZEND_VM_FP_GLOBAL_REG\n");
+ out($f,$m[1]."register zend_execute_data *execute_data __asm__(ZEND_VM_FP_GLOBAL_REG) = ex;\n");
+ out($f,"#else\n");
+ out($f,$m[1]."zend_execute_data *execute_data = ex;\n");
+ out($f,"#endif\n");
+ } else {
+ out($f,"#ifdef ZEND_VM_IP_GLOBAL_REG\n");
+ out($f,$m[1]."const zend_op *orig_opline = opline;\n");
+ out($f,"#endif\n");
+ out($f,"#ifdef ZEND_VM_FP_GLOBAL_REG\n");
+ out($f,$m[1]."zend_execute_data *orig_execute_data = execute_data;\n");
+ out($f,$m[1]."execute_data = ex;\n");
+ out($f,"#else\n");
+ out($f,$m[1]."zend_execute_data *execute_data = ex;\n");
+ out($f,"#endif\n");
+ }
+ break;
+ case "INTERNAL_LABELS":
+ if ($kind == ZEND_VM_KIND_GOTO || $kind == ZEND_VM_KIND_HYBRID) {
+ // Emit array of labels of opcode handlers and code for
+ // zend_opcode_handlers initialization
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ }
+ $prolog = $m[1];
+ out($f,$prolog."if (UNEXPECTED(execute_data == NULL)) {\n");
+ out($f,$prolog."\tstatic const void * const labels[] = {\n");
+ gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_GOTO : $kind, $prolog."\t\t", $specs);
+ out($f,$prolog."\t};\n");
+ out($f,$prolog."\tzend_opcode_handlers = (const void **) labels;\n");
+ out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(void*);\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,$prolog."\tmemset(&hybrid_halt_op, 0, sizeof(hybrid_halt_op));\n");
+ out($f,$prolog."\thybrid_halt_op.handler = (void*)&&HYBRID_HALT_LABEL;\n");
+ out($f,$prolog."\tgoto HYBRID_HALT_LABEL;\n");
+ } else {
+ out($f,$prolog."\treturn;\n");
+ }
+ out($f,$prolog."}\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#endif\n");
+ }
+ } else {
+ skip_blanks($f, $m[1], $m[3]);
+ }
+ break;
+ case "ZEND_VM_CONTINUE_LABEL":
+ if ($kind == ZEND_VM_KIND_CALL || $kind == ZEND_VM_KIND_HYBRID) {
+ // Only SWITCH dispatch method use it
+ out($f,"#if !defined(ZEND_VM_FP_GLOBAL_REG) || !defined(ZEND_VM_IP_GLOBAL_REG)\n");
+ out($f,$m[1]."\tint ret;".$m[3]."\n");
+ out($f,"#endif\n");
+ } else if ($kind == ZEND_VM_KIND_SWITCH) {
+ // Only SWITCH dispatch method use it
+ out($f,"zend_vm_continue:".$m[3]."\n");
+ } else {
+ skip_blanks($f, $m[1], $m[3]);
+ }
+ break;
+ case "ZEND_VM_DISPATCH":
+ // Emit code that dispatches to opcode handler
+ switch ($kind) {
+ case ZEND_VM_KIND_SWITCH:
+ out($f, $m[1]."dispatch_handler = OPLINE->handler;\nzend_vm_dispatch:\n".$m[1]."switch ((int)(uintptr_t)dispatch_handler)".$m[3]."\n");
+ break;
+ case ZEND_VM_KIND_GOTO:
+ out($f, $m[1]."goto *(void**)(OPLINE->handler);".$m[3]."\n");
+ break;
+ case ZEND_VM_KIND_HYBRID:
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ out($f, $m[1]."HYBRID_SWITCH()".$m[3]."\n");
+ out($f,"#else\n");
+ case ZEND_VM_KIND_CALL:
+ out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
+ out($f, $m[1]."((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
+ out($f, $m[1]."if (UNEXPECTED(!OPLINE))".$m[3]."\n");
+ out($f,"#else\n");
+ out($f, $m[1]."if (UNEXPECTED((ret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)) != 0))".$m[3]."\n");
+ out($f,"#endif\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#endif\n");
+ }
+ break;
+ }
+ break;
+ case "INTERNAL_EXECUTOR":
+ if ($kind != ZEND_VM_KIND_CALL) {
+ // Emit executor code
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ }
+ gen_executor_code($f, $spec, $kind, $m[1], $switch_labels);
+ }
+ if ($kind == ZEND_VM_KIND_CALL || $kind == ZEND_VM_KIND_HYBRID) {
+ // Executor is defined as a set of functions
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#else\n");
+ }
+ out($f,
+ "#ifdef ZEND_VM_FP_GLOBAL_REG\n" .
+ $m[1]."execute_data = orig_execute_data;\n" .
+ "# ifdef ZEND_VM_IP_GLOBAL_REG\n" .
+ $m[1]."opline = orig_opline;\n" .
+ "# endif\n" .
+ $m[1]."return;\n" .
+ "#else\n" .
+ $m[1]."if (EXPECTED(ret > 0)) {\n" .
+ $m[1]."\texecute_data = EG(current_execute_data);\n".
+ $m[1]."\tZEND_VM_LOOP_INTERRUPT_CHECK();\n".
+ $m[1]."} else {\n" .
+ "# ifdef ZEND_VM_IP_GLOBAL_REG\n" .
+ $m[1]."\topline = orig_opline;\n" .
+ "# endif\n".
+ $m[1]."\treturn;\n".
+ $m[1]."}\n".
+ "#endif\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#endif\n");
+ }
+ }
+ break;
+ case "EXTERNAL_EXECUTOR":
+ if ($kind == ZEND_VM_KIND_CALL) {
+ gen_executor_code($f, $spec, $kind, $m[1]);
+ }
+ break;
+ case "INITIALIZER_NAME":
+ out($f, $m[1].$initializer_name.$m[3]."\n");
+ break;
+ case "EXTERNAL_LABELS":
+ // Emit code that initializes zend_opcode_handlers array
+ $prolog = $m[1];
+ if ($kind == ZEND_VM_KIND_GOTO) {
+ // Labels are defined in the executor itself, so we call it
+ // with execute_data NULL and it sets zend_opcode_handlers array
+ out($f,$prolog."static const uint32_t specs[] = {\n");
+ gen_specs($f, $prolog."\t", $specs);
+ out($f,$prolog."};\n");
+ out($f,$prolog."zend_spec_handlers = specs;\n");
+ out($f,$prolog.$executor_name."_ex(NULL);\n");
+ } else {
+ out($f,$prolog."static const void * const labels[] = {\n");
+ gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_CALL : $kind, $prolog."\t", $specs, $switch_labels);
+ out($f,$prolog."};\n");
+ out($f,$prolog."static const uint32_t specs[] = {\n");
+ gen_specs($f, $prolog."\t", $specs);
+ out($f,$prolog."};\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
+ out($f,$prolog."zend_opcode_handler_funcs = labels;\n");
+ out($f,$prolog."zend_spec_handlers = specs;\n");
+ out($f,$prolog.$executor_name."_ex(NULL);\n");
+ out($f,"#else\n");
+ }
+ out($f,$prolog."zend_opcode_handlers = labels;\n");
+ out($f,$prolog."zend_handlers_count = sizeof(labels) / sizeof(void*);\n");
+ out($f,$prolog."zend_spec_handlers = specs;\n");
+ if ($kind == ZEND_VM_KIND_HYBRID) {
+ out($f,"#endif\n");
+ }
+ }
+ break;
+ default:
+ die("ERROR: Unknown keyword ".$m[2]." in skeleton file.\n");
+ }
+ } else {
+ // Copy the line as is
+ out($f, $line);
+ }
+ }
}
function parse_operand_spec($def, $lineno, $str, &$flags) {
- global $vm_op_decode;
-
- $flags = 0;
- $a = explode("|",$str);
- foreach($a as $val) {
- if (isset($vm_op_decode[$val])) {
- $flags |= $vm_op_decode[$val];
- } else {
- die("ERROR ($def:$lineno): Wrong operand type '$str'\n");
- }
- }
- if (!($flags & ZEND_VM_OP_SPEC)) {
- if (count($a) != 1) {
- die("ERROR ($def:$lineno): Wrong operand type '$str'\n");
- }
- $a = array("ANY");
- }
- return array_flip($a);
+ global $vm_op_decode;
+
+ $flags = 0;
+ $a = explode("|",$str);
+ foreach($a as $val) {
+ if (isset($vm_op_decode[$val])) {
+ $flags |= $vm_op_decode[$val];
+ } else {
+ die("ERROR ($def:$lineno): Wrong operand type '$str'\n");
+ }
+ }
+ if (!($flags & ZEND_VM_OP_SPEC)) {
+ if (count($a) != 1) {
+ die("ERROR ($def:$lineno): Wrong operand type '$str'\n");
+ }
+ $a = array("ANY");
+ }
+ return array_flip($a);
}
function parse_ext_spec($def, $lineno, $str) {
- global $vm_ext_decode;
-
- $flags = 0;
- $a = explode("|",$str);
- foreach($a as $val) {
- if (isset($vm_ext_decode[$val])) {
- $flags |= $vm_ext_decode[$val];
- } else {
- die("ERROR ($def:$lineno): Wrong extended_value type '$str'\n");
- }
- }
- return $flags;
+ global $vm_ext_decode;
+
+ $flags = 0;
+ $a = explode("|",$str);
+ foreach($a as $val) {
+ if (isset($vm_ext_decode[$val])) {
+ $flags |= $vm_ext_decode[$val];
+ } else {
+ die("ERROR ($def:$lineno): Wrong extended_value type '$str'\n");
+ }
+ }
+ return $flags;
}
function parse_spec_rules($def, $lineno, $str) {
- global $used_extra_spec;
-
- $ret = array();
- $a = explode(",", $str);
- foreach($a as $rule) {
- $n = strpos($rule, "=");
- if ($n !== false) {
- $id = trim(substr($rule, 0, $n));
- $val = trim(substr($rule, $n+1));
- switch ($id) {
- case "OP_DATA":
- $ret["OP_DATA"] = parse_operand_spec($def, $lineno, $val, $devnull);
- break;
- default:
- die("ERROR ($def:$lineno): Wrong specialization rules '$str'\n");
- }
- $used_extra_spec[$id] = 1;
- } else {
- switch ($rule) {
- case "RETVAL":
- $ret["RETVAL"] = array(0, 1);
- break;
- case "QUICK_ARG":
- $ret["QUICK_ARG"] = array(0, 1);
- break;
- case "SMART_BRANCH":
- $ret["SMART_BRANCH"] = array(0, 1, 2);
- break;
- case "NO_CONST_CONST":
- $ret["NO_CONST_CONST"] = array(1);
- break;
- case "COMMUTATIVE":
- $ret["COMMUTATIVE"] = array(1);
- break;
- case "ISSET":
- $ret["ISSET"] = array(0, 1);
- break;
- default:
- die("ERROR ($def:$lineno): Wrong specialization rules '$str'\n");
- }
- $used_extra_spec[$rule] = 1;
- }
- }
- return $ret;
+ global $used_extra_spec;
+
+ $ret = array();
+ $a = explode(",", $str);
+ foreach($a as $rule) {
+ $n = strpos($rule, "=");
+ if ($n !== false) {
+ $id = trim(substr($rule, 0, $n));
+ $val = trim(substr($rule, $n+1));
+ switch ($id) {
+ case "OP_DATA":
+ $ret["OP_DATA"] = parse_operand_spec($def, $lineno, $val, $devnull);
+ break;
+ default:
+ die("ERROR ($def:$lineno): Wrong specialization rules '$str'\n");
+ }
+ $used_extra_spec[$id] = 1;
+ } else {
+ switch ($rule) {
+ case "RETVAL":
+ $ret["RETVAL"] = array(0, 1);
+ break;
+ case "QUICK_ARG":
+ $ret["QUICK_ARG"] = array(0, 1);
+ break;
+ case "SMART_BRANCH":
+ $ret["SMART_BRANCH"] = array(0, 1, 2);
+ break;
+ case "NO_CONST_CONST":
+ $ret["NO_CONST_CONST"] = array(1);
+ break;
+ case "COMMUTATIVE":
+ $ret["COMMUTATIVE"] = array(1);
+ break;
+ case "ISSET":
+ $ret["ISSET"] = array(0, 1);
+ break;
+ default:
+ die("ERROR ($def:$lineno): Wrong specialization rules '$str'\n");
+ }
+ $used_extra_spec[$rule] = 1;
+ }
+ }
+ return $ret;
}
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*)?\)/",
+ $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";
}
function usage() {
- echo("\nUsage: php zend_vm_gen.php [options]\n".
- "\nOptions:".
- "\n --with-vm-kind=CALL|SWITCH|GOTO|HYBRID - select threading model (default is HYBRID)".
- "\n --without-specializer - disable executor specialization".
- "\n --with-lines - enable #line directives".
- "\n\n");
+ echo("\nUsage: php zend_vm_gen.php [options]\n".
+ "\nOptions:".
+ "\n --with-vm-kind=CALL|SWITCH|GOTO|HYBRID - select threading model (default is HYBRID)".
+ "\n --without-specializer - disable executor specialization".
+ "\n --with-lines - enable #line directives".
+ "\n\n");
}
// Parse arguments
for ($i = 1; $i < $argc; $i++) {
- if (strpos($argv[$i],"--with-vm-kind=") === 0) {
- $kind = substr($argv[$i], strlen("--with-vm-kind="));
- switch ($kind) {
- case "CALL":
- define("ZEND_VM_KIND", ZEND_VM_KIND_CALL);
- break;
- case "SWITCH":
- define("ZEND_VM_KIND", ZEND_VM_KIND_SWITCH);
- break;
- case "GOTO":
- define("ZEND_VM_KIND", ZEND_VM_KIND_GOTO);
- break;
- case "HYBRID":
- define("ZEND_VM_KIND", ZEND_VM_KIND_HYBRID);
- break;
- default:
- echo("ERROR: Invalid vm kind '$kind'\n");
- usage();
- die();
- }
- } else if ($argv[$i] == "--without-specializer") {
- // Disabling specialization
- define("ZEND_VM_SPEC", 0);
- } else if ($argv[$i] == "--with-lines") {
- // Enabling debugging using original zend_vm_def.h
- define("ZEND_VM_LINES", 1);
- } else if ($argv[$i] == "--help") {
- usage();
- exit();
- } else {
- echo("ERROR: Invalid option '".$argv[$i]."'\n");
- usage();
- die();
- }
+ if (strpos($argv[$i],"--with-vm-kind=") === 0) {
+ $kind = substr($argv[$i], strlen("--with-vm-kind="));
+ switch ($kind) {
+ case "CALL":
+ define("ZEND_VM_KIND", ZEND_VM_KIND_CALL);
+ break;
+ case "SWITCH":
+ define("ZEND_VM_KIND", ZEND_VM_KIND_SWITCH);
+ break;
+ case "GOTO":
+ define("ZEND_VM_KIND", ZEND_VM_KIND_GOTO);
+ break;
+ case "HYBRID":
+ define("ZEND_VM_KIND", ZEND_VM_KIND_HYBRID);
+ break;
+ default:
+ echo("ERROR: Invalid vm kind '$kind'\n");
+ usage();
+ die();
+ }
+ } else if ($argv[$i] == "--without-specializer") {
+ // Disabling specialization
+ define("ZEND_VM_SPEC", 0);
+ } else if ($argv[$i] == "--with-lines") {
+ // Enabling debugging using original zend_vm_def.h
+ define("ZEND_VM_LINES", 1);
+ } else if ($argv[$i] == "--help") {
+ usage();
+ exit();
+ } else {
+ echo("ERROR: Invalid option '".$argv[$i]."'\n");
+ usage();
+ die();
+ }
}
// Using defaults
if (!defined("ZEND_VM_KIND")) {
- // Using CALL threading by default
- define("ZEND_VM_KIND", ZEND_VM_KIND_HYBRID);
+ // Using CALL threading by default
+ define("ZEND_VM_KIND", ZEND_VM_KIND_HYBRID);
}
if (!defined("ZEND_VM_SPEC")) {
- // Using specialized executor by default
- define("ZEND_VM_SPEC", 1);
+ // Using specialized executor by default
+ define("ZEND_VM_SPEC", 1);
}
if (!defined("ZEND_VM_LINES")) {
- // Disabling #line directives
- define("ZEND_VM_LINES", 0);
+ // Disabling #line directives
+ define("ZEND_VM_LINES", 0);
}
gen_vm(__DIR__ . "/zend_vm_def.h", __DIR__ . "/zend_vm_execute.skl");
diff --git a/ext/ext_skel.php b/ext/ext_skel.php
index 43734a2a67..5c6835940f 100755
--- a/ext/ext_skel.php
+++ b/ext/ext_skel.php
@@ -21,8 +21,8 @@
/* {{{ error
*/
function error($message) {
- printf('Error: %s%s', $message, PHP_EOL);
- exit;
+ printf('Error: %s%s', $message, PHP_EOL);
+ exit;
}
/* }}} */
@@ -114,152 +114,152 @@ OPTIONS
--help This help
HELP;
- exit;
+ exit;
}
/* }}} */
/* {{{ task
*/
function task($label, $callback) {
- printf('%s... ', $label);
+ printf('%s... ', $label);
- $callback();
+ $callback();
- printf('done%s', PHP_EOL);
+ printf('done%s', PHP_EOL);
}
/* }}} */
/* {{{ 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/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);
}
/* }}} */
/* {{{ process_args
*/
function process_args($argv, $argc) {
- $options = [
- 'unix' => true,
- 'windows' => true,
- 'ext' => '',
- 'dir' => __DIR__ . DIRECTORY_SEPARATOR,
- 'skel' => __DIR__ . DIRECTORY_SEPARATOR . 'skeleton' . DIRECTORY_SEPARATOR,
- 'author' => false,
- 'experimental' => false,
- 'std' => false
- ];
-
- for($i = 1; $i < $argc; ++$i)
- {
- $val = $argv[$i];
-
- if($val[0] != '-' || $val[1] != '-')
- {
- continue;
- }
-
- switch($opt = strtolower(substr($val, 2)))
- {
- case 'help': {
- print_help();
- }
- case 'onlyunix': {
- $options['windows'] = false;
- }
- break;
- case 'onlywindows': {
- $options['unix'] = false;
- }
- break;
- case 'experimental': {
- $options['experimental'] = true;
- }
- break;
- case 'std': {
- $options['std'] = true;
- }
- break;
- case 'ext':
- case 'dir':
- case 'author': {
- if (!isset($argv[$i + 1]) || ($argv[$i + 1][0] == '-' && $argv[$i + 1][1] == '-')) {
- error('Argument "' . $val . '" expects a value, none passed');
- } else if ($opt == 'dir' && empty($argv[$i + 1])) {
- continue 2;
- }
-
- $options[$opt] = ($opt == 'dir' ? realpath($argv[$i + 1]) . DIRECTORY_SEPARATOR : $argv[$i + 1]);
- }
- break;
- default: {
- error('Unsupported argument "' . $val . '" passed');
- }
- }
- }
-
- if (empty($options['ext'])) {
- error('No extension name passed, use "--ext <name>"');
- } else if (!$options['unix'] && !$options['windows']) {
- error('Cannot pass both --onlyunix and --onlywindows');
- } else if (!is_dir($options['skel'])) {
- error('The skeleton directory was not found');
- }
-
- // Validate extension name
- if (!preg_match('/^[a-z][a-z0-9_]+$/i', $options['ext'])) {
- error('Invalid extension name. Valid names start with a letter,'
- .' followed by any number of letters, numbers, or underscores.'
- .' Using only lower case letters is preferred.');
- }
-
- $options['ext'] = str_replace(['\\', '/'], '', strtolower($options['ext']));
-
- return $options;
+ $options = [
+ 'unix' => true,
+ 'windows' => true,
+ 'ext' => '',
+ 'dir' => __DIR__ . DIRECTORY_SEPARATOR,
+ 'skel' => __DIR__ . DIRECTORY_SEPARATOR . 'skeleton' . DIRECTORY_SEPARATOR,
+ 'author' => false,
+ 'experimental' => false,
+ 'std' => false
+ ];
+
+ for($i = 1; $i < $argc; ++$i)
+ {
+ $val = $argv[$i];
+
+ if($val[0] != '-' || $val[1] != '-')
+ {
+ continue;
+ }
+
+ switch($opt = strtolower(substr($val, 2)))
+ {
+ case 'help': {
+ print_help();
+ }
+ case 'onlyunix': {
+ $options['windows'] = false;
+ }
+ break;
+ case 'onlywindows': {
+ $options['unix'] = false;
+ }
+ break;
+ case 'experimental': {
+ $options['experimental'] = true;
+ }
+ break;
+ case 'std': {
+ $options['std'] = true;
+ }
+ break;
+ case 'ext':
+ case 'dir':
+ case 'author': {
+ if (!isset($argv[$i + 1]) || ($argv[$i + 1][0] == '-' && $argv[$i + 1][1] == '-')) {
+ error('Argument "' . $val . '" expects a value, none passed');
+ } else if ($opt == 'dir' && empty($argv[$i + 1])) {
+ continue 2;
+ }
+
+ $options[$opt] = ($opt == 'dir' ? realpath($argv[$i + 1]) . DIRECTORY_SEPARATOR : $argv[$i + 1]);
+ }
+ break;
+ default: {
+ error('Unsupported argument "' . $val . '" passed');
+ }
+ }
+ }
+
+ if (empty($options['ext'])) {
+ error('No extension name passed, use "--ext <name>"');
+ } else if (!$options['unix'] && !$options['windows']) {
+ error('Cannot pass both --onlyunix and --onlywindows');
+ } else if (!is_dir($options['skel'])) {
+ error('The skeleton directory was not found');
+ }
+
+ // Validate extension name
+ if (!preg_match('/^[a-z][a-z0-9_]+$/i', $options['ext'])) {
+ error('Invalid extension name. Valid names start with a letter,'
+ .' followed by any number of letters, numbers, or underscores.'
+ .' Using only lower case letters is preferred.');
+ }
+
+ $options['ext'] = str_replace(['\\', '/'], '', strtolower($options['ext']));
+
+ return $options;
}
/* }}} */
/* {{{ 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"
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
@@ -276,141 +276,141 @@ function process_source_tags($file, $short_name) {
+----------------------------------------------------------------------+
*/
HEADER;
- } else {
- if ($options['author']) {
- $header = sprintf('/* %s extension for PHP (c) %d %s */', $options['ext'], date('Y'), $options['author']);
- } else {
- $header = sprintf('/* %s extension for PHP */', $options['ext']);
- }
- }
- }
-
- $source = str_replace('%HEADER%', $header, $source);
- }
-
- if (!file_put_contents($file, $source)) {
- error('Unable to save contents to file: ' . $short_name);
- }
+ } else {
+ if ($options['author']) {
+ $header = sprintf('/* %s extension for PHP (c) %d %s */', $options['ext'], date('Y'), $options['author']);
+ } else {
+ $header = sprintf('/* %s extension for PHP */', $options['ext']);
+ }
+ }
+ }
+
+ $source = str_replace('%HEADER%', $header, $source);
+ }
+
+ if (!file_put_contents($file, $source)) {
+ error('Unable to save contents to file: ' . $short_name);
+ }
}
/* }}} */
/* {{{ copy_config_scripts
*/
function copy_config_scripts() {
- global $options;
+ global $options;
- $files = [];
+ $files = [];
- if ($options['unix']) {
- $files[] = 'config.m4';
- }
+ if ($options['unix']) {
+ $files[] = 'config.m4';
+ }
- if ($options['windows']) {
- $files[] = 'config.w32';
- }
+ if ($options['windows']) {
+ $files[] = 'config.w32';
+ }
- $files[] = '.gitignore';
+ $files[] = '.gitignore';
- foreach($files as $config_script) {
- $new_config_script = $options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $config_script;
+ foreach($files as $config_script) {
+ $new_config_script = $options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $config_script;
- if (!copy($options['skel'] . $config_script . '.in', $new_config_script)) {
- error('Unable to copy config script: ' . $config_script);
- }
+ if (!copy($options['skel'] . $config_script . '.in', $new_config_script)) {
+ error('Unable to copy config script: ' . $config_script);
+ }
- process_source_tags($new_config_script, $config_script);
- }
+ process_source_tags($new_config_script, $config_script);
+ }
}
/* }}} */
/* {{{ 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);
+ }
}
/* }}} */
/* {{{ copy_tests
*/
function copy_tests() {
- global $options;
+ global $options;
- $test_files = glob($options['skel'] . 'tests/*', GLOB_MARK);
+ $test_files = glob($options['skel'] . 'tests/*', GLOB_MARK);
- if (!$test_files) {
- return;
- }
+ if (!$test_files) {
+ return;
+ }
- foreach ($test_files as $test) {
- if (is_dir($test)) {
- continue;
- }
+ foreach ($test_files as $test) {
+ if (is_dir($test)) {
+ continue;
+ }
- $new_test = str_replace([$options['skel'], '/'], ['', DIRECTORY_SEPARATOR], $test);
+ $new_test = str_replace([$options['skel'], '/'], ['', DIRECTORY_SEPARATOR], $test);
- if (!copy($test, $options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $new_test)) {
- error('Unable to copy file: ' . $new_test);
- }
+ if (!copy($test, $options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $new_test)) {
+ error('Unable to copy file: ' . $new_test);
+ }
- process_source_tags($options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $new_test, $new_test);
- }
+ process_source_tags($options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . $new_test, $new_test);
+ }
}
/* }}} */
if (PHP_SAPI != 'cli') {
- error('This script is only suited for CLI');
+ error('This script is only suited for CLI');
}
if ($argc < 1) {
- print_help();
- exit;
+ print_help();
+ exit;
}
$options = process_args($argv, $argc);
if (!$options['dir'] || !is_dir($options['dir'])) {
- error('The selected output directory does not exist');
+ error('The selected output directory does not exist');
} else if (is_dir($options['dir'] . $options['ext'])) {
- error('There is already a folder named "' . $options['ext'] . '" in the output directory');
+ error('There is already a folder named "' . $options['ext'] . '" in the output directory');
} else if (!mkdir($options['dir'] . $options['ext'])) {
- error('Unable to create extension directory in the output directory');
+ error('Unable to create extension directory in the output directory');
} else if (!mkdir($options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . 'tests')) {
- error('Unable to create the tests directory');
+ error('Unable to create the tests directory');
}
if ($options['experimental']) {
- print('Creating EXPERIMENTAL... ');
+ print('Creating EXPERIMENTAL... ');
- if (file_put_contents($options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . 'EXPERIMENTAL', '') === false) {
- error('Unable to create the EXPERIMENTAL file');
- }
+ if (file_put_contents($options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . 'EXPERIMENTAL', '') === false) {
+ error('Unable to create the EXPERIMENTAL file');
+ }
- printf('done%s', PHP_EOL);
+ printf('done%s', PHP_EOL);
}
if (!empty($options['author'])) {
- print('Creating CREDITS... ');
+ print('Creating CREDITS... ');
- if (!file_put_contents($options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . 'CREDITS', $options['ext'] . PHP_EOL . $options['author'])) {
- error('Unable to create the CREDITS file');
- }
+ if (!file_put_contents($options['dir'] . $options['ext'] . DIRECTORY_SEPARATOR . 'CREDITS', $options['ext'] . PHP_EOL . $options['author'])) {
+ error('Unable to create the CREDITS file');
+ }
- printf('done%s', PHP_EOL);
+ printf('done%s', PHP_EOL);
}
date_default_timezone_set('UTC');
diff --git a/ext/ffi/ffi.stub.php b/ext/ffi/ffi.stub.php
index 812217f990..ff73d2e124 100644
--- a/ext/ffi/ffi.stub.php
+++ b/ext/ffi/ffi.stub.php
@@ -17,13 +17,13 @@ class FFI
*/
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
diff --git a/ext/fileinfo/create_data_file.php b/ext/fileinfo/create_data_file.php
index c1284c60cb..e85be002b0 100755
--- a/ext/fileinfo/create_data_file.php
+++ b/ext/fileinfo/create_data_file.php
@@ -2,17 +2,17 @@
/* This is a generated file, do not modify */
/* Usage: php create_data_file.php /path/to/magic.mgc > data_file.c */
<?php
- $dta = file_get_contents( $argv[1] );
- $dta_l = strlen($dta);
- $j = 0;
+ $dta = file_get_contents( $argv[1] );
+ $dta_l = strlen($dta);
+ $j = 0;
- echo "const unsigned char php_magic_database[$dta_l] = {\n";
- for ($i = 0; $i < $dta_l; $i++) {
- printf("0x%02X, ", ord($dta[$i]));
- if ($j % 16 == 15) {
- echo "\n";
- }
- $j++;
- }
- echo "};\n";
+ echo "const unsigned char php_magic_database[$dta_l] = {\n";
+ for ($i = 0; $i < $dta_l; $i++) {
+ printf("0x%02X, ", ord($dta[$i]));
+ if ($j % 16 == 15) {
+ echo "\n";
+ }
+ $j++;
+ }
+ echo "};\n";
?>
diff --git a/ext/hash/bench.php b/ext/hash/bench.php
index a1cc4bedd1..60c038ca99 100755
--- a/ext/hash/bench.php
+++ b/ext/hash/bench.php
@@ -5,68 +5,68 @@
This gives rather interesting results :)
Measures on a Notebook P4M-1.7 256MB Windows 2000:
- sha1 0.556691
- tiger160,3 0.774469
- tiger192,3 0.776314
- tiger128,3 0.777004
- ripemd128 0.896674
- sha256 1.011164
- md5 1.016032
- tiger160,4 1.056617
- tiger128,4 1.063101
- tiger192,4 1.069258
- haval160,3 1.125099
- haval128,3 1.125679
- haval224,3 1.128017
- haval192,3 1.130026
- haval256,3 1.134846
- ripemd160 1.150693
- haval128,4 1.686261
- haval192,4 1.687274
- haval160,4 1.693091
- haval256,4 1.699323
- haval224,4 1.743094
- haval160,5 2.003452
- haval192,5 2.008341
- haval256,5 2.009048
- haval128,5 2.009555
- haval224,5 2.015539
- sha384 3.370734
- sha512 3.381121
- whirlpool 6.912327
- snefru 9.268168
+ sha1 0.556691
+ tiger160,3 0.774469
+ tiger192,3 0.776314
+ tiger128,3 0.777004
+ ripemd128 0.896674
+ sha256 1.011164
+ md5 1.016032
+ tiger160,4 1.056617
+ tiger128,4 1.063101
+ tiger192,4 1.069258
+ haval160,3 1.125099
+ haval128,3 1.125679
+ haval224,3 1.128017
+ haval192,3 1.130026
+ haval256,3 1.134846
+ ripemd160 1.150693
+ haval128,4 1.686261
+ haval192,4 1.687274
+ haval160,4 1.693091
+ haval256,4 1.699323
+ haval224,4 1.743094
+ haval160,5 2.003452
+ haval192,5 2.008341
+ haval256,5 2.009048
+ haval128,5 2.009555
+ haval224,5 2.015539
+ sha384 3.370734
+ sha512 3.381121
+ whirlpool 6.912327
+ snefru 9.268168
Measures on a Desktop P4-2.4 512MB Debian (Linux-2.4):
- md5 0.147739
- haval128,3 0.317006
- haval192,3 0.317524
- haval256,3 0.317526
- haval160,3 0.323035
- haval224,3 0.333318
- ripemd128 0.353447
- sha1 0.376200
- ripemd160 0.413758
- sha256 0.435957
- haval160,4 0.452357
- haval224,4 0.454531
- haval128,4 0.458026
- haval256,4 0.459051
- haval192,4 0.468094
- haval128,5 0.524262
- haval160,5 0.529573
- haval224,5 0.533655
- haval256,5 0.534446
- haval192,5 0.543726
- tiger128,3 0.577975
- tiger160,3 0.579951
- tiger192,3 0.597111
- tiger192,4 0.781408
- tiger160,4 0.801243
- tiger128,4 0.812239
- sha512 1.298627
- sha384 1.313607
- whirlpool 1.556159
- snefru 5.703742
+ md5 0.147739
+ haval128,3 0.317006
+ haval192,3 0.317524
+ haval256,3 0.317526
+ haval160,3 0.323035
+ haval224,3 0.333318
+ ripemd128 0.353447
+ sha1 0.376200
+ ripemd160 0.413758
+ sha256 0.435957
+ haval160,4 0.452357
+ haval224,4 0.454531
+ haval128,4 0.458026
+ haval256,4 0.459051
+ haval192,4 0.468094
+ haval128,5 0.524262
+ haval160,5 0.529573
+ haval224,5 0.533655
+ haval256,5 0.534446
+ haval192,5 0.543726
+ tiger128,3 0.577975
+ tiger160,3 0.579951
+ tiger192,3 0.597111
+ tiger192,4 0.781408
+ tiger160,4 0.801243
+ tiger128,4 0.812239
+ sha512 1.298627
+ sha384 1.313607
+ whirlpool 1.556159
+ snefru 5.703742
*/
@@ -76,17 +76,17 @@ $data = file_get_contents(__FILE__);
$time = array();
for ($j = 0; $j < 10; $j++) {
- foreach (hash_algos() as $algo) {
- $start = microtime(true);
- for ($i = 0; $i < 1000; $i++) {
- hash($algo, $data);
- }
- $time[$algo] += microtime(true)-$start;
- }
+ foreach (hash_algos() as $algo) {
+ $start = microtime(true);
+ for ($i = 0; $i < 1000; $i++) {
+ hash($algo, $data);
+ }
+ $time[$algo] += microtime(true)-$start;
+ }
}
asort($time, SORT_NUMERIC);
foreach ($time as $a => $t) {
- printf("%-12s %02.6f\n", $a, $t);
+ printf("%-12s %02.6f\n", $a, $t);
}
?>
diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c
index 685b9d62ea..105d5a3587 100644
--- a/ext/pdo_firebird/firebird_statement.c
+++ b/ext/pdo_firebird/firebird_statement.c
@@ -625,7 +625,7 @@ static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_dat
{
zend_long lval;
double dval;
-
+
if ((Z_STRLEN_P(parameter) == 0)) {
*(FB_BOOLEAN*)var->sqldata = FB_FALSE;
break;
@@ -663,7 +663,7 @@ static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_dat
break;
}
#endif
-
+
/* check if a NULL should be inserted */
switch (Z_TYPE_P(parameter)) {
diff --git a/ext/pdo_firebird/pdo_firebird.c b/ext/pdo_firebird/pdo_firebird.c
index 79b3c396f1..d8e55957f2 100644
--- a/ext/pdo_firebird/pdo_firebird.c
+++ b/ext/pdo_firebird/pdo_firebird.c
@@ -82,7 +82,7 @@ PHP_MINFO_FUNCTION(pdo_firebird) /* {{{ */
{
char version[64];
isc_get_client_version(version);
-
+
php_info_print_table_start();
php_info_print_table_header(2, "PDO Driver for Firebird", "enabled");
php_info_print_table_row(2, "Client Library Version", version);
diff --git a/ext/pdo_mysql/get_error_codes.php b/ext/pdo_mysql/get_error_codes.php
index 4c956f8c4e..27910f8dad 100755
--- a/ext/pdo_mysql/get_error_codes.php
+++ b/ext/pdo_mysql/get_error_codes.php
@@ -1,28 +1,28 @@
#!/usr/bin/env php
<?php
- $codes = array();
- $maxlen = 0;
+ $codes = array();
+ $maxlen = 0;
- while (!feof(STDIN)) {
- $line = fgets(STDIN);
+ while (!feof(STDIN)) {
+ $line = fgets(STDIN);
- if (ereg('^\{[[:space:]]+(ER_.*)[[:space:]]+,[[:space:]]*"(.*)",[[:space:]]*"(.*)"', $line, $matches)) {
- $codes[$matches[1]] = $matches[2];
- $maxlen = max($maxlen, strlen($matches[1]));
- }
- }
+ if (ereg('^\{[[:space:]]+(ER_.*)[[:space:]]+,[[:space:]]*"(.*)",[[:space:]]*"(.*)"', $line, $matches)) {
+ $codes[$matches[1]] = $matches[2];
+ $maxlen = max($maxlen, strlen($matches[1]));
+ }
+ }
- if (empty($codes)) {
- fputs(STDERR, "input doesn't look like a MySQL sql_state.h file\n");
- exit(3);
- }
+ if (empty($codes)) {
+ fputs(STDERR, "input doesn't look like a MySQL sql_state.h file\n");
+ exit(3);
+ }
- echo "/* DO NOT EDIT THIS FILE!!! It is auto generated by get_error_codes.php */\n";
- foreach ($codes as $code => $state) {
- echo "#ifdef $code\n";
- printf(" case %-{$maxlen}s: return \"%s\";\n", $code, $state);
- echo "#endif\n";
- }
+ echo "/* DO NOT EDIT THIS FILE!!! It is auto generated by get_error_codes.php */\n";
+ foreach ($codes as $code => $state) {
+ echo "#ifdef $code\n";
+ printf(" case %-{$maxlen}s: return \"%s\";\n", $code, $state);
+ echo "#endif\n";
+ }
?>
diff --git a/ext/pdo_sqlite/sqlite_statement.c b/ext/pdo_sqlite/sqlite_statement.c
index f937c4263b..db1bbf9b14 100644
--- a/ext/pdo_sqlite/sqlite_statement.c
+++ b/ext/pdo_sqlite/sqlite_statement.c
@@ -57,7 +57,7 @@ static void pdo_sqlite_stmt_set_column_count(pdo_stmt_t *stmt, int new_count)
}
/*
- * The column count has not changed : no need to reload columns description
+ * The column count has not changed : no need to reload columns description
* Note: Do not handle attribute name change, without column count change
*/
if (new_count == stmt->column_count) {
diff --git a/ext/phar/build_precommand.php b/ext/phar/build_precommand.php
index c2fe9c8e52..c427ffbd5b 100755
--- a/ext/phar/build_precommand.php
+++ b/ext/phar/build_precommand.php
@@ -10,44 +10,44 @@
* Phar Command
*/
foreach(array("SPL", "Reflection", "Phar") as $ext) {
- if (!extension_loaded($ext)) {
- echo "$argv[0] requires PHP extension $ext.\n";
- exit(1);
- }
+ if (!extension_loaded($ext)) {
+ echo "$argv[0] requires PHP extension $ext.\n";
+ exit(1);
+ }
}
<?php
$classes = array(
- 'DirectoryTreeIterator',
- 'DirectoryGraphIterator',
- 'InvertedRegexIterator',
- 'CLICommand',
- 'PharCommand',
- );
+ 'DirectoryTreeIterator',
+ 'DirectoryGraphIterator',
+ 'InvertedRegexIterator',
+ 'CLICommand',
+ 'PharCommand',
+ );
foreach($classes as $name) {
- echo "if (!class_exists('$name', 0))\n{\n";
- $f = file(dirname(__FILE__) . '/phar/' . strtolower($name) . '.inc');
- unset($f[0]);
- $c = count($f);
- while ($c && (strlen($f[$c]) == 0 || $f[$c] == "\n" || $f[$c] == "\r\n")) {
- unset($f[$c--]);
- }
- if (substr($f[$c], -2) == "\r\n") {
- $f[$c] = substr($f[$c], 0, -2);
- }
- if (substr($f[$c], -1) == "\n") {
- $f[$c] = substr($f[$c], 0, -1);
- }
- if (substr($f[$c], -2) == '?>') {
- $f[$c] = substr($f[$c], 0,-2);
- }
- while ($c && (strlen($f[$c]) == 0 || $f[$c] == "\n" || $f[$c] == "\r\n")) {
- unset($f[$c--]);
- }
- echo join('', $f);
- echo "\n}\n\n";
+ echo "if (!class_exists('$name', 0))\n{\n";
+ $f = file(dirname(__FILE__) . '/phar/' . strtolower($name) . '.inc');
+ unset($f[0]);
+ $c = count($f);
+ while ($c && (strlen($f[$c]) == 0 || $f[$c] == "\n" || $f[$c] == "\r\n")) {
+ unset($f[$c--]);
+ }
+ if (substr($f[$c], -2) == "\r\n") {
+ $f[$c] = substr($f[$c], 0, -2);
+ }
+ if (substr($f[$c], -1) == "\n") {
+ $f[$c] = substr($f[$c], 0, -1);
+ }
+ if (substr($f[$c], -2) == '?>') {
+ $f[$c] = substr($f[$c], 0,-2);
+ }
+ while ($c && (strlen($f[$c]) == 0 || $f[$c] == "\n" || $f[$c] == "\r\n")) {
+ unset($f[$c--]);
+ }
+ echo join('', $f);
+ echo "\n}\n\n";
}
echo 'new PharCommand($argc, $argv);'."\n";
diff --git a/ext/phar/makestub.php b/ext/phar/makestub.php
index 2feb730845..42ca3d62d3 100644
--- a/ext/phar/makestub.php
+++ b/ext/phar/makestub.php
@@ -4,18 +4,18 @@ $s = str_replace("\r", '', file_get_contents(dirname(__FILE__) . '/shortarc.php'
$s .= "\nExtract_Phar::go();\n__HALT_COMPILER();";
$news = '';
foreach (token_get_all($s) as $token) {
- if (is_array($token)) {
- if ($token[0] == T_COMMENT) {
- $token[1] = '';
- }
- if ($token[0] == T_WHITESPACE) {
- $n = str_repeat("\n", substr_count($token[1], "\n"));
- $token[1] = strlen($n) ? $n : ' ';
- }
- $news .= $token[1];
- } else {
- $news .= $token;
- }
+ if (is_array($token)) {
+ if ($token[0] == T_COMMENT) {
+ $token[1] = '';
+ }
+ if ($token[0] == T_WHITESPACE) {
+ $n = str_repeat("\n", substr_count($token[1], "\n"));
+ $token[1] = strlen($n) ? $n : ' ';
+ }
+ $news .= $token[1];
+ } else {
+ $news .= $token;
+ }
}
$s = $news . ' ?>';
$slen = strlen($s) - strlen('index.php') - strlen("000");
@@ -55,50 +55,50 @@ $s1split = str_split($s1, 2046);
$s3split = str_split($s3, 2046);
$took = false;
foreach ($s1split as $i => $chunk) {
- if ($took) {
- $s1split[$i] = substr($chunk, 1);
- $took = false;
- }
- if ($chunk[strlen($chunk) - 1] == '\\') {
- $s1split[$i] .= $s1split[$i + 1][0];
- $took = true;
- }
+ if ($took) {
+ $s1split[$i] = substr($chunk, 1);
+ $took = false;
+ }
+ if ($chunk[strlen($chunk) - 1] == '\\') {
+ $s1split[$i] .= $s1split[$i + 1][0];
+ $took = true;
+ }
}
foreach ($s3split as $i => $chunk) {
- if ($took) {
- $s3split[$i] = substr($chunk, 1);
- $took = false;
- }
- if ($chunk[strlen($chunk) - 1] == '\\') {
- $s3split[$i] .= $s3split[$i + 1][0];
- $took = true;
- }
+ if ($took) {
+ $s3split[$i] = substr($chunk, 1);
+ $took = false;
+ }
+ if ($chunk[strlen($chunk) - 1] == '\\') {
+ $s3split[$i] .= $s3split[$i + 1][0];
+ $took = true;
+ }
}
$stub .= "\tstatic const char newstub0[] = \"" . $webs . '";
';
foreach ($s1split as $i => $chunk) {
- $s1count = $i + 1;
- $stub .= "\tstatic const char newstub1_" . $i . '[] = "' . $chunk . '";
+ $s1count = $i + 1;
+ $stub .= "\tstatic const char newstub1_" . $i . '[] = "' . $chunk . '";
';
}
$stub .= "\tstatic const char newstub2[] = \"" . $s2 . "\";
";
foreach ($s3split as $i => $chunk) {
- $s3count = $i + 1;
- $stub .= "\tstatic const char newstub3_" . $i . '[] = "' . $chunk . '";
+ $s3count = $i + 1;
+ $stub .= "\tstatic const char newstub3_" . $i . '[] = "' . $chunk . '";
';
}
$stub .= "\n\tstatic const int newstub_len = " . $slen . ";
\t*len = spprintf(stub, name_len + web_len + newstub_len, \"%s%s" . str_repeat('%s', $s1count) . '%s%s%d'
- . str_repeat('%s', $s3count) . '", newstub0, web';
+ . str_repeat('%s', $s3count) . '", newstub0, web';
foreach ($s1split as $i => $unused) {
- $stub .= ', newstub1_' . $i;
+ $stub .= ', newstub1_' . $i;
}
$stub .= ', index_php, newstub2';
$stub .= ", name_len + web_len + newstub_len";
foreach ($s3split as $i => $unused) {
- $stub .= ', newstub3_' . $i;
+ $stub .= ', newstub3_' . $i;
}
$stub .= ");
}";
diff --git a/ext/phar/phar/phar.php b/ext/phar/phar/phar.php
index 13538777a5..53aa76f60a 100755
--- a/ext/phar/phar/phar.php
+++ b/ext/phar/phar/phar.php
@@ -12,37 +12,37 @@
if (!extension_loaded('phar'))
{
- if (!class_exists('PHP_Archive', 0)) {
- echo "Neither Extension Phar nor class PHP_Archive are available.\n";
- exit(1);
- }
- if (!in_array('phar', stream_get_wrappers())) {
- stream_wrapper_register('phar', 'PHP_Archive');
- }
- if (!class_exists('Phar',0)) {
- require 'phar://'.__FILE__.'/phar.inc';
- }
+ if (!class_exists('PHP_Archive', 0)) {
+ echo "Neither Extension Phar nor class PHP_Archive are available.\n";
+ exit(1);
+ }
+ if (!in_array('phar', stream_get_wrappers())) {
+ stream_wrapper_register('phar', 'PHP_Archive');
+ }
+ if (!class_exists('Phar',0)) {
+ require 'phar://'.__FILE__.'/phar.inc';
+ }
}
foreach(array("SPL", "Reflection") as $ext)
{
- if (!extension_loaded($ext)) {
- echo "$argv[0] requires PHP extension $ext.\n";
- exit(1);
- }
+ if (!extension_loaded($ext)) {
+ echo "$argv[0] requires PHP extension $ext.\n";
+ exit(1);
+ }
}
function command_include($file)
{
- $file = 'phar://' . __FILE__ . '/' . $file;
- if (file_exists($file)) {
- include($file);
- }
+ $file = 'phar://' . __FILE__ . '/' . $file;
+ if (file_exists($file)) {
+ include($file);
+ }
}
function command_autoload($classname)
{
- command_include(strtolower($classname) . '.inc');
+ command_include(strtolower($classname) . '.inc');
}
Phar::mapPhar();
diff --git a/ext/phar/phar_object.stub.php b/ext/phar/phar_object.stub.php
index a1719fddb9..2af9d5bc5e 100644
--- a/ext/phar/phar_object.stub.php
+++ b/ext/phar/phar_object.stub.php
@@ -96,7 +96,7 @@ class Phar extends RecursiveDirectoryIterator implements Countable, ArrayAccess
*/
public function offsetExists($entry) {}
- /**
+ /**
* @param string $entry
* @return PharFileInfo
*/
@@ -130,7 +130,7 @@ class Phar extends RecursiveDirectoryIterator implements Countable, ArrayAccess
/** @return void */
public function setSignatureAlgorithm(int $algorithm, string $privatekey = UNKNOWN) {}
- /**
+ /**
* @param resource $newstub
* @return bool
*/
@@ -318,7 +318,7 @@ class PharData extends RecursiveDirectoryIterator implements Countable, ArrayAcc
/** @return void */
public function setSignatureAlgorithm(int $algorithm, string $privatekey = UNKNOWN) {}
- /**
+ /**
* @param resource $newstub
* @return bool
*/
diff --git a/ext/snmp/snmp.stub.php b/ext/snmp/snmp.stub.php
index 965a0fbc8d..ce085637be 100644
--- a/ext/snmp/snmp.stub.php
+++ b/ext/snmp/snmp.stub.php
@@ -78,43 +78,43 @@ 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() {}
+ 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() {}
}
diff --git a/ext/zip/examples/addglob.php b/ext/zip/examples/addglob.php
index 3c432f0be5..13ea83b02a 100644
--- a/ext/zip/examples/addglob.php
+++ b/ext/zip/examples/addglob.php
@@ -5,8 +5,8 @@ $z->open('a.zip', ZIPARCHIVE::CREATE);
/* or 'remove_all_path' => 0*/
$options = array(
- 'remove_path' => '/home/francis/myimages',
- 'add_path' => 'images/',
+ 'remove_path' => '/home/francis/myimages',
+ 'add_path' => 'images/',
);
$found = $z->addGlob("/home/pierre/cvs/gd/libgd/tests/*.png", 0, $options);
var_dump($found);
diff --git a/ext/zip/examples/create.php b/ext/zip/examples/create.php
index a41c8e6d0b..d835704c8e 100644
--- a/ext/zip/examples/create.php
+++ b/ext/zip/examples/create.php
@@ -9,9 +9,9 @@ $zip = new ZipArchive();
$filename = "./test112.zip";
if (!$zip->open($filename, ZIPARCHIVE::CREATE)) {
- exit("cannot open <$filename>\n");
+ exit("cannot open <$filename>\n");
} else {
- echo "file <$filename> OK\n";
+ echo "file <$filename> OK\n";
}
$zip->addFromString("testfilephp.txt" . time(), "#1 This is a test string added as testfilephp.txt.\n");
diff --git a/ext/zip/examples/dir.php b/ext/zip/examples/dir.php
index c362a72ba3..6fe56c0b9b 100644
--- a/ext/zip/examples/dir.php
+++ b/ext/zip/examples/dir.php
@@ -15,7 +15,7 @@ echo "filename: " . $za->filename . "\n";
echo "comment: " . $za->comment . "\n";
for ($i=0; $i<$za->numFiles;$i++) {
- echo "index: $i\n";
- print_r($za->statIndex($i));
+ echo "index: $i\n";
+ print_r($za->statIndex($i));
}
echo "numFile:" . $za->numFiles . "\n";
diff --git a/ext/zip/examples/encryption.php b/ext/zip/examples/encryption.php
index 9ef7dd8497..42d3850404 100644
--- a/ext/zip/examples/encryption.php
+++ b/ext/zip/examples/encryption.php
@@ -40,9 +40,9 @@ $zip->close();
echo "== Stream with context\n";
$ctx = stream_context_create(array(
- 'zip' => array(
- 'password' => $pass
- )
+ 'zip' => array(
+ 'password' => $pass
+ )
));
$text = file_get_contents("zip://$name#$file", false, $ctx);
printf("Size = %d\n", strlen($text));
diff --git a/ext/zip/examples/extract.php b/ext/zip/examples/extract.php
index 5276b0dca5..01a9c75aee 100644
--- a/ext/zip/examples/extract.php
+++ b/ext/zip/examples/extract.php
@@ -19,9 +19,9 @@ echo $zip->filename . "\n";
var_dump($zip);
$files = array('test', 'testdir/test2');
if (!$zip->extractTo("./testext/path/to", $files)) {
- echo "error!\n";
- echo $zip->status . "\n";
- echo $zip->statusSys . "\n";
+ echo "error!\n";
+ echo $zip->status . "\n";
+ echo $zip->statusSys . "\n";
}
diff --git a/ext/zip/examples/extractAll.php b/ext/zip/examples/extractAll.php
index d318a453df..69286b93ec 100644
--- a/ext/zip/examples/extractAll.php
+++ b/ext/zip/examples/extractAll.php
@@ -15,9 +15,9 @@ echo $zip->filename . "\n";
var_dump($zip);
$files = array('test', 'testdir/test2');
if (!$zip->extractTo("./testext/path/to")) {
- echo "error!\n";
- echo $zip->status . "\n";
- echo $zip->statusSys . "\n";
+ echo "error!\n";
+ echo $zip->status . "\n";
+ echo $zip->statusSys . "\n";
}
diff --git a/ext/zip/examples/fopen.php b/ext/zip/examples/fopen.php
index 80de5d052a..4dcedba74a 100644
--- a/ext/zip/examples/fopen.php
+++ b/ext/zip/examples/fopen.php
@@ -6,11 +6,11 @@ if (!extension_loaded('zip')) {
$fp = fopen('zip://' . dirname(__FILE__) . '/test.zip#test', 'r');
if (!$fp) {
- exit("cannot open\n");
+ exit("cannot open\n");
}
while (!feof($fp)) {
- $contents .= fread($fp, 2);
- echo "$contents\n";
+ $contents .= fread($fp, 2);
+ echo "$contents\n";
}
fclose($fp);
@@ -25,7 +25,7 @@ $fp = $z->getStream('test');
var_dump($fp);
if(!$fp) exit("\n");
while (!feof($fp)) {
- $contents .= fread($fp, 2);
+ $contents .= fread($fp, 2);
}
fclose($fp);
diff --git a/ext/zip/examples/get_set_comments.php b/ext/zip/examples/get_set_comments.php
index 600b51138d..a9faf08f33 100644
--- a/ext/zip/examples/get_set_comments.php
+++ b/ext/zip/examples/get_set_comments.php
@@ -7,9 +7,9 @@ $z->open('t.zip');
print_r($z);
for ($i=0; $i<$z->numFiles; $i++) {
- echo "index: $i\n";
- print_r($z->getCommentIndex($i));
- echo "\n\n";
+ echo "index: $i\n";
+ print_r($z->getCommentIndex($i));
+ echo "\n\n";
}
echo "foobar/ " . $z->getCommentName('foobar/') . "\n";
@@ -22,9 +22,9 @@ $z->setCommentName('foobar/', 'new comment foobar/');
$z->setArchiveComment( 'new archive comment');
for ($i=0; $i<$z->numFiles; $i++) {
- echo "index: $i\n";
- print_r($z->getCommentIndex($i));
- echo "\n\n";
+ echo "index: $i\n";
+ print_r($z->getCommentIndex($i));
+ echo "\n\n";
}
echo $z->getCommentName('foobar/') . "\n";
diff --git a/ext/zip/examples/odt.php b/ext/zip/examples/odt.php
index 195c781e33..3f923296a1 100644
--- a/ext/zip/examples/odt.php
+++ b/ext/zip/examples/odt.php
@@ -5,16 +5,16 @@ $reader = new XMLReader();
$reader->open('zip://' . dirname(__FILE__) . '/test.odt#meta.xml');
$odt_meta = array();
while ($reader->read()) {
- if ($reader->nodeType == XMLREADER::ELEMENT) {
- $elm = $reader->name;
- } else {
- if ($reader->nodeType == XMLREADER::END_ELEMENT && $reader->name == 'office:meta') {
- break;
- }
- if (!trim($reader->value)) {
- continue;
- }
- $odt_meta[$elm] = $reader->value;
- }
+ if ($reader->nodeType == XMLREADER::ELEMENT) {
+ $elm = $reader->name;
+ } else {
+ if ($reader->nodeType == XMLREADER::END_ELEMENT && $reader->name == 'office:meta') {
+ break;
+ }
+ if (!trim($reader->value)) {
+ continue;
+ }
+ $odt_meta[$elm] = $reader->value;
+ }
}
print_r($odt_meta);
diff --git a/ext/zip/examples/oldapi.php b/ext/zip/examples/oldapi.php
index 82a6277f3a..216de4837e 100644
--- a/ext/zip/examples/oldapi.php
+++ b/ext/zip/examples/oldapi.php
@@ -4,14 +4,14 @@ $zip = zip_open('examples/test1.zip');
var_dump($zip);
if ($zip) {
- $i = 0;
- while ($zip_entry = zip_read($zip)) {
- var_dump($zip_entry);
- $txt = zip_entry_read($zip_entry, 10);
+ $i = 0;
+ while ($zip_entry = zip_read($zip)) {
+ var_dump($zip_entry);
+ $txt = zip_entry_read($zip_entry, 10);
echo $i . ": " . $txt . "size: " . zip_entry_filesize($zip_entry) .
- "comp_method: " . zip_entry_compressionmethod($zip_entry) .
- "\n";
- $i++;
- }
- var_dump($zip_entry);
+ "comp_method: " . zip_entry_compressionmethod($zip_entry) .
+ "\n";
+ $i++;
+ }
+ var_dump($zip_entry);
}
diff --git a/ext/zip/examples/set_compression.php b/ext/zip/examples/set_compression.php
index 1efd88c7f1..49494e0bf7 100644
--- a/ext/zip/examples/set_compression.php
+++ b/ext/zip/examples/set_compression.php
@@ -8,7 +8,7 @@ $zip = new ZipArchive();
$filename = "a.zip";
if (!$zip->open($filename, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) {
- exit("cannot open <$filename>\n");
+ exit("cannot open <$filename>\n");
}
$zip->addFromString("testfilephp.txt", "#1 This is a test string added as testfilephp.txt.\n");
diff --git a/main/php_variables.c b/main/php_variables.c
index 826b3bcfa5..8edbcac628 100644
--- a/main/php_variables.c
+++ b/main/php_variables.c
@@ -571,7 +571,7 @@ void _php_import_environment_variables(zval *array_ptr)
php_register_variable_quick(*env, name_len, &val, Z_ARRVAL_P(array_ptr));
}
}
-
+
tsrm_env_unlock();
}
diff --git a/run-tests.php b/run-tests.php
index a5698882db..1a59ca5f8e 100755
--- a/run-tests.php
+++ b/run-tests.php
@@ -40,42 +40,42 @@
*/
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 ! |
@@ -84,452 +84,452 @@ function main()
+-----------------------------------------------------------+
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 (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
Synopsis:
php run-tests.php [options] [files] [directories]
@@ -615,297 +615,297 @@ 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 (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")) {
- function hrtime(bool $as_num = false)
- {
- $t = microtime(true);
+ function hrtime(bool $as_num = false)
+ {
+ $t = microtime(true);
- if ($as_num) {
- return $t * 1000000000;
- }
+ if ($as_num) {
+ return $t * 1000000000;
+ }
- $s = floor($t);
- return array(0 => $s, 1 => ($t - $s) * 1000000000);
- }
+ $s = floor($t);
+ return array(0 => $s, 1 => ($t - $s) * 1000000000);
+ }
}
function verify_config()
{
- global $php;
+ global $php;
- if (empty($php) || !file_exists($php)) {
- error('environment variable TEST_PHP_EXECUTABLE must be set to specify PHP executable!');
- }
+ if (empty($php) || !file_exists($php)) {
+ error('environment variable TEST_PHP_EXECUTABLE must be set to specify PHP executable!');
+ }
- if (!is_executable($php)) {
- error("invalid PHP executable specified by TEST_PHP_EXECUTABLE = $php");
- }
+ if (!is_executable($php)) {
+ error("invalid PHP executable specified by TEST_PHP_EXECUTABLE = $php");
+ }
}
function write_information()
{
- global $php, $php_cgi, $phpdbg, $php_info, $user_tests, $ini_overwrites, $pass_options, $exts_to_test, $valgrind, $no_file_cache;
+ global $php, $php_cgi, $phpdbg, $php_info, $user_tests, $ini_overwrites, $pass_options, $exts_to_test, $valgrind, $no_file_cache;
- // Get info from php
- $info_file = __DIR__ . '/run-test-info.php';
- @unlink($info_file);
- $php_info = '<?php echo "
+ // Get info from php
+ $info_file = __DIR__ . '/run-test-info.php';
+ @unlink($info_file);
+ $php_info = '<?php echo "
PHP_SAPI : " , PHP_SAPI , "
PHP_VERSION : " , phpversion() , "
ZEND_VERSION: " , zend_version() , "
PHP_OS : " , PHP_OS , " - " , php_uname() , "
INI actual : " , realpath(get_cfg_var("cfg_file_path")) , "
More .INIs : " , (function_exists(\'php_ini_scanned_files\') ? str_replace("\n","", php_ini_scanned_files()) : "** not determined **"); ?>';
- save_text($info_file, $php_info);
- $info_params = array();
- settings2array($ini_overwrites, $info_params);
- $info_params = settings2params($info_params);
- $php_info = `$php $pass_options $info_params $no_file_cache "$info_file"`;
- define('TESTED_PHP_VERSION', `$php -n -r "echo PHP_VERSION;"`);
-
- if ($php_cgi && $php != $php_cgi) {
- $php_info_cgi = `$php_cgi $pass_options $info_params $no_file_cache -q "$info_file"`;
- $php_info_sep = "\n---------------------------------------------------------------------";
- $php_cgi_info = "$php_info_sep\nPHP : $php_cgi $php_info_cgi$php_info_sep";
- } else {
- $php_cgi_info = '';
- }
-
- if ($phpdbg) {
- $phpdbg_info = `$phpdbg $pass_options $info_params $no_file_cache -qrr "$info_file"`;
- $php_info_sep = "\n---------------------------------------------------------------------";
- $phpdbg_info = "$php_info_sep\nPHP : $phpdbg $phpdbg_info$php_info_sep";
- } else {
- $phpdbg_info = '';
- }
-
- if (function_exists('opcache_invalidate')) {
- opcache_invalidate($info_file, true);
- }
- @unlink($info_file);
-
- // load list of enabled extensions
- save_text($info_file,
- '<?php echo str_replace("Zend OPcache", "opcache", implode(",", get_loaded_extensions())); ?>');
- $exts_to_test = explode(',', `$php $pass_options $info_params $no_file_cache "$info_file"`);
- // check for extensions that need special handling and regenerate
- $info_params_ex = array(
- 'session' => array('session.auto_start=0'),
- 'tidy' => array('tidy.clean_output=0'),
- 'zlib' => array('zlib.output_compression=Off'),
- 'xdebug' => array('xdebug.default_enable=0'),
- 'mbstring' => array('mbstring.func_overload=0'),
- );
-
- foreach ($info_params_ex as $ext => $ini_overwrites_ex) {
- if (in_array($ext, $exts_to_test)) {
- $ini_overwrites = array_merge($ini_overwrites, $ini_overwrites_ex);
- }
- }
-
- if (function_exists('opcache_invalidate')) {
- opcache_invalidate($info_file, true);
- }
- @unlink($info_file);
-
- // Write test context information.
- echo "
+ save_text($info_file, $php_info);
+ $info_params = array();
+ settings2array($ini_overwrites, $info_params);
+ $info_params = settings2params($info_params);
+ $php_info = `$php $pass_options $info_params $no_file_cache "$info_file"`;
+ define('TESTED_PHP_VERSION', `$php -n -r "echo PHP_VERSION;"`);
+
+ if ($php_cgi && $php != $php_cgi) {
+ $php_info_cgi = `$php_cgi $pass_options $info_params $no_file_cache -q "$info_file"`;
+ $php_info_sep = "\n---------------------------------------------------------------------";
+ $php_cgi_info = "$php_info_sep\nPHP : $php_cgi $php_info_cgi$php_info_sep";
+ } else {
+ $php_cgi_info = '';
+ }
+
+ if ($phpdbg) {
+ $phpdbg_info = `$phpdbg $pass_options $info_params $no_file_cache -qrr "$info_file"`;
+ $php_info_sep = "\n---------------------------------------------------------------------";
+ $phpdbg_info = "$php_info_sep\nPHP : $phpdbg $phpdbg_info$php_info_sep";
+ } else {
+ $phpdbg_info = '';
+ }
+
+ if (function_exists('opcache_invalidate')) {
+ opcache_invalidate($info_file, true);
+ }
+ @unlink($info_file);
+
+ // load list of enabled extensions
+ save_text($info_file,
+ '<?php echo str_replace("Zend OPcache", "opcache", implode(",", get_loaded_extensions())); ?>');
+ $exts_to_test = explode(',', `$php $pass_options $info_params $no_file_cache "$info_file"`);
+ // check for extensions that need special handling and regenerate
+ $info_params_ex = array(
+ 'session' => array('session.auto_start=0'),
+ 'tidy' => array('tidy.clean_output=0'),
+ 'zlib' => array('zlib.output_compression=Off'),
+ 'xdebug' => array('xdebug.default_enable=0'),
+ 'mbstring' => array('mbstring.func_overload=0'),
+ );
+
+ foreach ($info_params_ex as $ext => $ini_overwrites_ex) {
+ if (in_array($ext, $exts_to_test)) {
+ $ini_overwrites = array_merge($ini_overwrites, $ini_overwrites_ex);
+ }
+ }
+
+ if (function_exists('opcache_invalidate')) {
+ opcache_invalidate($info_file, true);
+ }
+ @unlink($info_file);
+
+ // Write test context information.
+ echo "
=====================================================================
PHP : $php $php_info $php_cgi_info $phpdbg_info
CWD : " . TEST_PHP_SRCDIR . "
Extra dirs : ";
- foreach ($user_tests as $test_dir) {
- echo "{$test_dir}\n ";
- }
- echo "
+ foreach ($user_tests as $test_dir) {
+ echo "{$test_dir}\n ";
+ }
+ echo "
VALGRIND : " . ($valgrind ? $valgrind->getHeader() : 'Not used') . "
=====================================================================
";
@@ -913,194 +913,194 @@ VALGRIND : " . ($valgrind ? $valgrind->getHeader() : 'Not used') . "
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 (!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)
{
- global $test_files, $exts_to_test, $ignored_by_ext, $exts_skipped;
-
- $o = opendir($dir) or error("cannot open directory: $dir");
-
- while (($name = readdir($o)) !== false) {
-
- if (is_dir("{$dir}/{$name}") && !in_array($name, array('.', '..', '.svn'))) {
- $skip_ext = ($is_ext_dir && !in_array(strtolower($name), $exts_to_test));
- if ($skip_ext) {
- $exts_skipped++;
- }
- find_files("{$dir}/{$name}", false, $ignore || $skip_ext);
- }
-
- // Cleanup any left-over tmp files from last run.
- if (substr($name, -4) == '.tmp') {
- @unlink("$dir/$name");
- continue;
- }
-
- // Otherwise we're only interested in *.phpt files.
- if (substr($name, -5) == '.phpt') {
- if ($ignore) {
- $ignored_by_ext++;
- } else {
- $testfile = realpath("{$dir}/{$name}");
- $test_files[] = $testfile;
- }
- }
- }
-
- closedir($o);
+ global $test_files, $exts_to_test, $ignored_by_ext, $exts_skipped;
+
+ $o = opendir($dir) or error("cannot open directory: $dir");
+
+ while (($name = readdir($o)) !== false) {
+
+ if (is_dir("{$dir}/{$name}") && !in_array($name, array('.', '..', '.svn'))) {
+ $skip_ext = ($is_ext_dir && !in_array(strtolower($name), $exts_to_test));
+ if ($skip_ext) {
+ $exts_skipped++;
+ }
+ find_files("{$dir}/{$name}", false, $ignore || $skip_ext);
+ }
+
+ // Cleanup any left-over tmp files from last run.
+ if (substr($name, -4) == '.tmp') {
+ @unlink("$dir/$name");
+ continue;
+ }
+
+ // Otherwise we're only interested in *.phpt files.
+ if (substr($name, -5) == '.phpt') {
+ if ($ignore) {
+ $ignored_by_ext++;
+ } else {
+ $testfile = realpath("{$dir}/{$name}");
+ $test_files[] = $testfile;
+ }
+ }
+ }
+
+ closedir($o);
}
function test_name($name)
{
- if (is_array($name)) {
- return $name[0] . ':' . $name[1];
- } else {
- return $name;
- }
+ if (is_array($name)) {
+ return $name[0] . ':' . $name[1];
+ } else {
+ return $name;
+ }
}
function test_sort($a, $b)
{
- $a = test_name($a);
- $b = test_name($b);
-
- $ta = strpos($a, TEST_PHP_SRCDIR . "/tests") === 0 ? 1 + (strpos($a,
- TEST_PHP_SRCDIR . "/tests/run-test") === 0 ? 1 : 0) : 0;
- $tb = strpos($b, TEST_PHP_SRCDIR . "/tests") === 0 ? 1 + (strpos($b,
- TEST_PHP_SRCDIR . "/tests/run-test") === 0 ? 1 : 0) : 0;
-
- if ($ta == $tb) {
- return strcmp($a, $b);
- } else {
- return $tb - $ta;
- }
+ $a = test_name($a);
+ $b = test_name($b);
+
+ $ta = strpos($a, TEST_PHP_SRCDIR . "/tests") === 0 ? 1 + (strpos($a,
+ TEST_PHP_SRCDIR . "/tests/run-test") === 0 ? 1 : 0) : 0;
+ $tb = strpos($b, TEST_PHP_SRCDIR . "/tests") === 0 ? 1 + (strpos($b,
+ TEST_PHP_SRCDIR . "/tests/run-test") === 0 ? 1 : 0) : 0;
+
+ if ($ta == $tb) {
+ return strcmp($a, $b);
+ } else {
+ return $tb - $ta;
+ }
}
@@ -1111,44 +1111,44 @@ function test_sort($a, $b)
function mail_qa_team($data, $status = false)
{
- $url_bits = parse_url(QA_SUBMISSION_PAGE);
-
- if ($proxy = getenv('http_proxy')) {
- $proxy = parse_url($proxy);
- $path = $url_bits['host'] . $url_bits['path'];
- $host = $proxy['host'];
- if (empty($proxy['port'])) {
- $proxy['port'] = 80;
- }
- $port = $proxy['port'];
- } else {
- $path = $url_bits['path'];
- $host = $url_bits['host'];
- $port = empty($url_bits['port']) ? 80 : $port = $url_bits['port'];
- }
-
- $data = "php_test_data=" . urlencode(base64_encode(str_replace("\00", '[0x0]', $data)));
- $data_length = strlen($data);
-
- $fs = fsockopen($host, $port, $errno, $errstr, 10);
-
- if (!$fs) {
- return false;
- }
-
- $php_version = urlencode(TESTED_PHP_VERSION);
-
- echo "\nPosting to " . QA_SUBMISSION_PAGE . "\n";
- fwrite($fs, "POST " . $path . "?status=$status&version=$php_version HTTP/1.1\r\n");
- fwrite($fs, "Host: " . $host . "\r\n");
- fwrite($fs, "User-Agent: QA Browser 0.1\r\n");
- fwrite($fs, "Content-Type: application/x-www-form-urlencoded\r\n");
- fwrite($fs, "Content-Length: " . $data_length . "\r\n\r\n");
- fwrite($fs, $data);
- fwrite($fs, "\r\n\r\n");
- fclose($fs);
-
- return 1;
+ $url_bits = parse_url(QA_SUBMISSION_PAGE);
+
+ if ($proxy = getenv('http_proxy')) {
+ $proxy = parse_url($proxy);
+ $path = $url_bits['host'] . $url_bits['path'];
+ $host = $proxy['host'];
+ if (empty($proxy['port'])) {
+ $proxy['port'] = 80;
+ }
+ $port = $proxy['port'];
+ } else {
+ $path = $url_bits['path'];
+ $host = $url_bits['host'];
+ $port = empty($url_bits['port']) ? 80 : $port = $url_bits['port'];
+ }
+
+ $data = "php_test_data=" . urlencode(base64_encode(str_replace("\00", '[0x0]', $data)));
+ $data_length = strlen($data);
+
+ $fs = fsockopen($host, $port, $errno, $errstr, 10);
+
+ if (!$fs) {
+ return false;
+ }
+
+ $php_version = urlencode(TESTED_PHP_VERSION);
+
+ echo "\nPosting to " . QA_SUBMISSION_PAGE . "\n";
+ fwrite($fs, "POST " . $path . "?status=$status&version=$php_version HTTP/1.1\r\n");
+ fwrite($fs, "Host: " . $host . "\r\n");
+ fwrite($fs, "User-Agent: QA Browser 0.1\r\n");
+ fwrite($fs, "Content-Type: application/x-www-form-urlencoded\r\n");
+ fwrite($fs, "Content-Length: " . $data_length . "\r\n\r\n");
+ fwrite($fs, $data);
+ fwrite($fs, "\r\n\r\n");
+ fclose($fs);
+
+ return 1;
}
@@ -1158,19 +1158,19 @@ function mail_qa_team($data, $status = false)
function save_text($filename, $text, $filename_copy = null)
{
- global $DETAILED;
+ global $DETAILED;
- if ($filename_copy && $filename_copy != $filename) {
- if (file_put_contents($filename_copy, $text, FILE_BINARY) === false) {
- error("Cannot open file '" . $filename_copy . "' (save_text)");
- }
- }
+ if ($filename_copy && $filename_copy != $filename) {
+ if (file_put_contents($filename_copy, $text, FILE_BINARY) === false) {
+ error("Cannot open file '" . $filename_copy . "' (save_text)");
+ }
+ }
- if (file_put_contents($filename, $text, FILE_BINARY) === false) {
- error("Cannot open file '" . $filename . "' (save_text)");
- }
+ if (file_put_contents($filename, $text, FILE_BINARY) === false) {
+ error("Cannot open file '" . $filename . "' (save_text)");
+ }
- if (1 < $DETAILED) echo "
+ if (1 < $DETAILED) echo "
FILE $filename {{{
$text
}}}
@@ -1183,557 +1183,557 @@ $text
function error_report($testname, $logname, $tested)
{
- $testname = realpath($testname);
- $logname = realpath($logname);
-
- switch (strtoupper(getenv('TEST_PHP_ERROR_STYLE'))) {
- case 'MSVC':
- echo $testname . "(1) : $tested\n";
- echo $logname . "(1) : $tested\n";
- break;
- case 'EMACS':
- echo $testname . ":1: $tested\n";
- echo $logname . ":1: $tested\n";
- break;
- }
+ $testname = realpath($testname);
+ $logname = realpath($logname);
+
+ switch (strtoupper(getenv('TEST_PHP_ERROR_STYLE'))) {
+ case 'MSVC':
+ echo $testname . "(1) : $tested\n";
+ echo $logname . "(1) : $tested\n";
+ break;
+ case 'EMACS':
+ echo $testname . ":1: $tested\n";
+ echo $logname . ":1: $tested\n";
+ break;
+ }
}
function system_with_timeout($commandline, $env = null, $stdin = null, $captureStdIn = true, $captureStdOut = true, $captureStdErr = true)
{
- global $valgrind;
-
- $data = '';
-
- $bin_env = array();
- foreach ((array)$env as $key => $value) {
- $bin_env[$key] = $value;
- }
-
- $descriptorspec = array();
- if ($captureStdIn) {
- $descriptorspec[0] = array('pipe', 'r');
- }
- if ($captureStdOut) {
- $descriptorspec[1] = array('pipe', 'w');
- }
- if ($captureStdErr) {
- $descriptorspec[2] = array('pipe', 'w');
- }
- $proc = proc_open($commandline, $descriptorspec, $pipes, TEST_PHP_SRCDIR, $bin_env, array('suppress_errors' => true));
-
- if (!$proc) {
- return false;
- }
-
- if ($captureStdIn) {
- if (!is_null($stdin)) {
- fwrite($pipes[0], $stdin);
- }
- fclose($pipes[0]);
- unset($pipes[0]);
- }
-
- $timeout = $valgrind ? 300 : ($env['TEST_TIMEOUT'] ?? 60);
-
- while (true) {
- /* hide errors from interrupted syscalls */
- $r = $pipes;
- $w = null;
- $e = null;
-
- $n = @stream_select($r, $w, $e, $timeout);
-
- if ($n === false) {
- break;
- } else if ($n === 0) {
- /* timed out */
- $data .= "\n ** ERROR: process timed out **\n";
- proc_terminate($proc, 9);
- return $data;
- } else if ($n > 0) {
- if ($captureStdOut) {
- $line = fread($pipes[1], 8192);
- } elseif ($captureStdErr) {
- $line = fread($pipes[2], 8192);
- } else {
- $line = '';
- }
- if (strlen($line) == 0) {
- /* EOF */
- break;
- }
- $data .= $line;
- }
- }
-
- $stat = proc_get_status($proc);
-
- if ($stat['signaled']) {
- $data .= "\nTermsig=" . $stat['stopsig'] . "\n";
- }
- if ($stat["exitcode"] > 128 && $stat["exitcode"] < 160) {
- $data .= "\nTermsig=" . ($stat["exitcode"] - 128) . "\n";
- }
-
- proc_close($proc);
- return $data;
+ global $valgrind;
+
+ $data = '';
+
+ $bin_env = array();
+ foreach ((array)$env as $key => $value) {
+ $bin_env[$key] = $value;
+ }
+
+ $descriptorspec = array();
+ if ($captureStdIn) {
+ $descriptorspec[0] = array('pipe', 'r');
+ }
+ if ($captureStdOut) {
+ $descriptorspec[1] = array('pipe', 'w');
+ }
+ if ($captureStdErr) {
+ $descriptorspec[2] = array('pipe', 'w');
+ }
+ $proc = proc_open($commandline, $descriptorspec, $pipes, TEST_PHP_SRCDIR, $bin_env, array('suppress_errors' => true));
+
+ if (!$proc) {
+ return false;
+ }
+
+ if ($captureStdIn) {
+ if (!is_null($stdin)) {
+ fwrite($pipes[0], $stdin);
+ }
+ fclose($pipes[0]);
+ unset($pipes[0]);
+ }
+
+ $timeout = $valgrind ? 300 : ($env['TEST_TIMEOUT'] ?? 60);
+
+ while (true) {
+ /* hide errors from interrupted syscalls */
+ $r = $pipes;
+ $w = null;
+ $e = null;
+
+ $n = @stream_select($r, $w, $e, $timeout);
+
+ if ($n === false) {
+ break;
+ } else if ($n === 0) {
+ /* timed out */
+ $data .= "\n ** ERROR: process timed out **\n";
+ proc_terminate($proc, 9);
+ return $data;
+ } else if ($n > 0) {
+ if ($captureStdOut) {
+ $line = fread($pipes[1], 8192);
+ } elseif ($captureStdErr) {
+ $line = fread($pipes[2], 8192);
+ } else {
+ $line = '';
+ }
+ if (strlen($line) == 0) {
+ /* EOF */
+ break;
+ }
+ $data .= $line;
+ }
+ }
+
+ $stat = proc_get_status($proc);
+
+ if ($stat['signaled']) {
+ $data .= "\nTermsig=" . $stat['stopsig'] . "\n";
+ }
+ if ($stat["exitcode"] > 128 && $stat["exitcode"] < 160) {
+ $data .= "\nTermsig=" . ($stat["exitcode"] - 128) . "\n";
+ }
+
+ proc_close($proc);
+ return $data;
}
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;
+
+ /* 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, $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 = [];
+ 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 = [];
- $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.");
- }
+ 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.");
+ }
}
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);
+ $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);
- }
- }
+ foreach ($children as $child) {
+ if ($child) {
+ proc_terminate($child);
+ }
+ }
}
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;
- }
- }
+ 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;
+ }
+ }
}
//
@@ -1741,18 +1741,18 @@ function run_worker() {
//
function show_file_block($file, $block, $section = null)
{
- global $cfg;
+ global $cfg;
- if ($cfg['show'][$file]) {
+ if ($cfg['show'][$file]) {
- if (is_null($section)) {
- $section = strtoupper($file);
- }
+ if (is_null($section)) {
+ $section = strtoupper($file);
+ }
- echo "\n========" . $section . "========\n";
- echo rtrim($block);
- echo "\n========DONE========\n";
- }
+ echo "\n========" . $section . "========\n";
+ echo rtrim($block);
+ echo "\n========DONE========\n";
+ }
}
//
@@ -1760,698 +1760,698 @@ function show_file_block($file, $block, $section = null)
//
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 "
+ 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 (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'] : '';
+ // Load the sections of the test file.
+ $section_text = array('TEST' => '');
- 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;
- }
+ $fp = fopen($file, "rb") or error("Cannot open test file: $file");
- if (array_key_exists('POST_RAW', $section_text) && !empty($section_text['POST_RAW'])) {
+ $bork_info = null;
- $post = trim($section_text['POST_RAW']);
- $raw_lines = explode("\n", $post);
+ if (!feof($fp)) {
+ $line = fgets($fp);
- $request = '';
- $started = false;
+ 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]";
+ }
- 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;
- }
+ $section = 'TEST';
+ $secfile = false;
+ $secdone = false;
- if ($started) {
- $request .= "\n";
- }
+ while (!feof($fp)) {
+ $line = fgets($fp);
- $started = true;
- $request .= $line;
- }
+ if ($line === false) {
+ break;
+ }
- $env['CONTENT_LENGTH'] = strlen($request);
- $env['REQUEST_METHOD'] = 'POST';
+ // 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;
+ }
- if (empty($request)) {
- junit_mark_test_as('BORK', $shortname, $tested, null, 'empty $request');
- return 'BORKED';
- }
+ // Add to the section text.
+ if (!$secdone) {
+ $section_text[$section] .= $line;
+ }
- save_text($tmp_post, $request);
- $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
+ // End of actual test?
+ if ($secfile && preg_match('/^===DONE===\s*$/', $line)) {
+ $secdone = true;
+ }
+ }
- } elseif (array_key_exists('PUT', $section_text) && !empty($section_text['PUT'])) {
+ // 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'])) {
- $post = trim($section_text['PUT']);
- $raw_lines = explode("\n", $post);
+ if ($IN_REDIRECT) {
+ $bork_info = "Can't redirect a test from within a redirected test";
+ }
- $request = '';
- $started = false;
+ } else {
- foreach ($raw_lines as $line) {
+ 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 (empty($env['CONTENT_TYPE']) && preg_match('/^Content-Type:(.*)/i', $line, $res)) {
- $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1]));
- continue;
- }
+ 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 = '';
+ }
- if ($started) {
- $request .= "\n";
- }
+ $tested = trim($section_text['TEST']);
- $started = true;
- $request .= $line;
- }
+ /* 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;
+ }
- $env['CONTENT_LENGTH'] = strlen($request);
- $env['REQUEST_METHOD'] = 'PUT';
+ /* 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 (empty($request)) {
- junit_mark_test_as('BORK', $shortname, $tested, null, 'empty $request');
- return 'BORKED';
- }
+ if (isset($phpdbg)) {
+ $php = $phpdbg . ' -qIb';
- save_text($tmp_post, $request);
- $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
+ // 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");
- } else if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) {
+ junit_init_suite(junit_get_suitename_for($shortname));
+ junit_mark_test_as('SKIP', $shortname, $tested, 0, 'phpdbg not available');
+ return 'SKIPPED';
+ }
+ }
- $post = trim($section_text['POST']);
- $content_length = strlen($post);
- save_text($tmp_post, $post);
+ if (!$SHOW_ONLY_GROUPS && !$workerID) {
+ show_test($test_idx, $shortname);
+ }
- $env['REQUEST_METHOD'] = 'POST';
- if (empty($env['CONTENT_TYPE'])) {
- $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
- }
+ if (is_array($IN_REDIRECT)) {
+ $temp_dir = $test_dir = $IN_REDIRECT['dir'];
+ } else {
+ $temp_dir = $test_dir = realpath(dirname($file));
+ }
- if (empty($env['CONTENT_LENGTH'])) {
- $env['CONTENT_LENGTH'] = $content_length;
- }
+ 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);
+ }
- $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
+ // 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];
+ }
+ }
+ }
- } else if (array_key_exists('GZIP_POST', $section_text) && !empty($section_text['GZIP_POST'])) {
+ // 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;
+ }
+ }
+ }
+ }
- $post = trim($section_text['GZIP_POST']);
- $post = gzencode($post, 9, FORCE_GZIP);
- $env['HTTP_CONTENT_ENCODING'] = 'gzip';
+ // additional ini overwrites
+ //$ini_overwrites[] = 'setting=value';
+ settings2array($ini_overwrites, $ini_settings);
- save_text($tmp_post, $post);
- $content_length = strlen($post);
+ $orig_ini_settings = settings2params($ini_settings);
- $env['REQUEST_METHOD'] = 'POST';
- $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
- $env['CONTENT_LENGTH'] = $content_length;
+ // 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);
- $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
+ $env['TEST_PHP_EXTRA_ARGS'] = $pass_options . ' ' . $ini_settings;
- } 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);
+ // Check if test should be skipped.
+ $info = '';
+ $warn = false;
- $env['REQUEST_METHOD'] = 'POST';
- $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
- $env['CONTENT_LENGTH'] = $content_length;
+ if (array_key_exists('SKIPIF', $section_text)) {
- $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
+ 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;" : "";
- } else {
+ if ($valgrind) {
+ $env['USE_ZEND_ALLOC'] = '0';
+ $env['ZEND_DONT_UNLOAD_MODULES'] = 1;
+ }
- $env['REQUEST_METHOD'] = 'GET';
- $env['CONTENT_TYPE'] = '';
- $env['CONTENT_LENGTH'] = '';
+ junit_start_timer($shortname);
- $cmd = "$php $pass_options $ini_settings -f \"$test_file\" $args$cmdRedirect";
- }
+ $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);
- if ($valgrind) {
- $env['USE_ZEND_ALLOC'] = '0';
- $env['ZEND_DONT_UNLOAD_MODULES'] = 1;
+ junit_finish_timer($shortname);
- $cmd = $valgrind->wrapCommand($cmd, $memcheck_filename, strpos($test_file, "pcre") !== false);
- }
+ if (!$cfg['keep']['skip']) {
+ @unlink($test_skipif);
+ }
- if ($DETAILED) echo "
+ 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'] : '';
+
+ 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'])) {
+
+ $post = trim($section_text['POST_RAW']);
+ $raw_lines = explode("\n", $post);
+
+ $request = '';
+ $started = false;
+
+ 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 ($started) {
+ $request .= "\n";
+ }
+
+ $started = true;
+ $request .= $line;
+ }
+
+ $env['CONTENT_LENGTH'] = strlen($request);
+ $env['REQUEST_METHOD'] = 'POST';
+
+ 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\"";
+
+ } elseif (array_key_exists('PUT', $section_text) && !empty($section_text['PUT'])) {
+
+ $post = trim($section_text['PUT']);
+ $raw_lines = explode("\n", $post);
+
+ $request = '';
+ $started = false;
+
+ 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 ($started) {
+ $request .= "\n";
+ }
+
+ $started = true;
+ $request .= $line;
+ }
+
+ $env['CONTENT_LENGTH'] = strlen($request);
+ $env['REQUEST_METHOD'] = 'PUT';
+
+ 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\"";
+
+ } 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);
+
+ $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;
+ }
+
+ $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'])) {
+
+ $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);
+
+ $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\"";
+
+ } 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;
+
+ $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\"";
+
+ } else {
+
+ $env['REQUEST_METHOD'] = 'GET';
+ $env['CONTENT_TYPE'] = '';
+ $env['CONTENT_LENGTH'] = '';
+
+ $cmd = "$php $pass_options $ini_settings -f \"$test_file\" $args$cmdRedirect";
+ }
+
+ if ($valgrind) {
+ $env['USE_ZEND_ALLOC'] = '0';
+ $env['ZEND_DONT_UNLOAD_MODULES'] = 1;
+
+ $cmd = $valgrind->wrapCommand($cmd, $memcheck_filename, strpos($test_file, "pcre") !== false);
+ }
+
+ if ($DETAILED) echo "
CONTENT_LENGTH = " . $env['CONTENT_LENGTH'] . "
CONTENT_TYPE = " . $env['CONTENT_TYPE'] . "
PATH_TRANSLATED = " . $env['PATH_TRANSLATED'] . "
@@ -2463,578 +2463,578 @@ 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 = !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) {
- error("Cannot create test shell script - $sh_filename");
- }
- chmod($sh_filename, 0755);
+ error("Cannot create test shell script - $sh_filename");
+ }
+ chmod($sh_filename, 0755);
- // write .log
- if (strpos($log_format, 'L') !== false && file_put_contents($log_filename, "
+ // write .log
+ if (strpos($log_format, 'L') !== false && file_put_contents($log_filename, "
---- EXPECTED OUTPUT
$wanted
---- ACTUAL OUTPUT
$output
---- FAILED
", FILE_BINARY) === false) {
- error("Cannot create test log - $log_filename");
- error_report($file, $log_filename, $tested);
- }
- }
+ error("Cannot create test log - $log_filename");
+ error_report($file, $log_filename, $tested);
+ }
+ }
- if ($valgrind && $leaked && $cfg["show"]["mem"]) {
- show_file_block('mem', file_get_contents($memcheck_filename));
- }
+ if ($valgrind && $leaked && $cfg["show"]["mem"]) {
+ show_file_block('mem', file_get_contents($memcheck_filename));
+ }
- show_result(implode('&', $restype), $tested, $tested_file, $info, $temp_filenames);
+ show_result(implode('&', $restype), $tested, $tested_file, $info, $temp_filenames);
- foreach ($restype as $type) {
- $PHP_FAILED_TESTS[$type . 'ED'][] = array(
- 'name' => $file,
- 'test_name' => (is_array($IN_REDIRECT) ? $IN_REDIRECT['via'] : '') . $tested . " [$tested_file]",
- 'output' => $output_filename,
- 'diff' => $diff_filename,
- 'info' => $info,
- );
- }
+ foreach ($restype as $type) {
+ $PHP_FAILED_TESTS[$type . 'ED'][] = array(
+ 'name' => $file,
+ 'test_name' => (is_array($IN_REDIRECT) ? $IN_REDIRECT['via'] : '') . $tested . " [$tested_file]",
+ 'output' => $output_filename,
+ 'diff' => $diff_filename,
+ 'info' => $info,
+ );
+ }
- $diff = empty($diff) ? '' : preg_replace('/\e/', '<esc>', $diff);
+ $diff = empty($diff) ? '' : preg_replace('/\e/', '<esc>', $diff);
- junit_mark_test_as($restype, $shortname, $tested, null, $info, $diff);
+ junit_mark_test_as($restype, $shortname, $tested, null, $info, $diff);
- return $restype[0] . 'ED';
+ return $restype[0] . 'ED';
}
function comp_line($l1, $l2, $is_reg)
{
- if ($is_reg) {
- return preg_match('/^' . $l1 . '$/s', $l2);
- } else {
- return !strcmp($l1, $l2);
- }
+ if ($is_reg) {
+ return preg_match('/^' . $l1 . '$/s', $l2);
+ } else {
+ return !strcmp($l1, $l2);
+ }
}
function count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $idx2, $cnt1, $cnt2, $steps)
{
- $equal = 0;
-
- while ($idx1 < $cnt1 && $idx2 < $cnt2 && comp_line($ar1[$idx1], $ar2[$idx2], $is_reg)) {
- $idx1++;
- $idx2++;
- $equal++;
- $steps--;
- }
- if (--$steps > 0) {
- $eq1 = 0;
- $st = $steps / 2;
-
- for ($ofs1 = $idx1 + 1; $ofs1 < $cnt1 && $st-- > 0; $ofs1++) {
- $eq = @count_array_diff($ar1, $ar2, $is_reg, $w, $ofs1, $idx2, $cnt1, $cnt2, $st);
-
- if ($eq > $eq1) {
- $eq1 = $eq;
- }
- }
-
- $eq2 = 0;
- $st = $steps;
-
- for ($ofs2 = $idx2 + 1; $ofs2 < $cnt2 && $st-- > 0; $ofs2++) {
- $eq = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $ofs2, $cnt1, $cnt2, $st);
- if ($eq > $eq2) {
- $eq2 = $eq;
- }
- }
-
- if ($eq1 > $eq2) {
- $equal += $eq1;
- } else if ($eq2 > 0) {
- $equal += $eq2;
- }
- }
-
- return $equal;
+ $equal = 0;
+
+ while ($idx1 < $cnt1 && $idx2 < $cnt2 && comp_line($ar1[$idx1], $ar2[$idx2], $is_reg)) {
+ $idx1++;
+ $idx2++;
+ $equal++;
+ $steps--;
+ }
+ if (--$steps > 0) {
+ $eq1 = 0;
+ $st = $steps / 2;
+
+ for ($ofs1 = $idx1 + 1; $ofs1 < $cnt1 && $st-- > 0; $ofs1++) {
+ $eq = @count_array_diff($ar1, $ar2, $is_reg, $w, $ofs1, $idx2, $cnt1, $cnt2, $st);
+
+ if ($eq > $eq1) {
+ $eq1 = $eq;
+ }
+ }
+
+ $eq2 = 0;
+ $st = $steps;
+
+ for ($ofs2 = $idx2 + 1; $ofs2 < $cnt2 && $st-- > 0; $ofs2++) {
+ $eq = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $ofs2, $cnt1, $cnt2, $st);
+ if ($eq > $eq2) {
+ $eq2 = $eq;
+ }
+ }
+
+ if ($eq1 > $eq2) {
+ $equal += $eq1;
+ } else if ($eq2 > 0) {
+ $equal += $eq2;
+ }
+ }
+
+ return $equal;
}
function generate_array_diff($ar1, $ar2, $is_reg, $w)
{
- $idx1 = 0;
- $cnt1 = @count($ar1);
- $idx2 = 0;
- $cnt2 = @count($ar2);
- $diff = array();
- $old1 = array();
- $old2 = array();
-
- while ($idx1 < $cnt1 && $idx2 < $cnt2) {
-
- if (comp_line($ar1[$idx1], $ar2[$idx2], $is_reg)) {
- $idx1++;
- $idx2++;
- continue;
- } else {
-
- $c1 = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1 + 1, $idx2, $cnt1, $cnt2, 10);
- $c2 = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $idx2 + 1, $cnt1, $cnt2, 10);
-
- if ($c1 > $c2) {
- $old1[$idx1] = sprintf("%03d- ", $idx1 + 1) . $w[$idx1++];
- } else if ($c2 > 0) {
- $old2[$idx2] = sprintf("%03d+ ", $idx2 + 1) . $ar2[$idx2++];
- } else {
- $old1[$idx1] = sprintf("%03d- ", $idx1 + 1) . $w[$idx1++];
- $old2[$idx2] = sprintf("%03d+ ", $idx2 + 1) . $ar2[$idx2++];
- }
- }
- }
-
- reset($old1);
- $k1 = key($old1);
- $l1 = -2;
- reset($old2);
- $k2 = key($old2);
- $l2 = -2;
-
- while ($k1 !== null || $k2 !== null) {
-
- if ($k1 == $l1 + 1 || $k2 === null) {
- $l1 = $k1;
- $diff[] = current($old1);
- $k1 = next($old1) ? key($old1) : null;
- } else if ($k2 == $l2 + 1 || $k1 === null) {
- $l2 = $k2;
- $diff[] = current($old2);
- $k2 = next($old2) ? key($old2) : null;
- } else if ($k1 < $k2) {
- $l1 = $k1;
- $diff[] = current($old1);
- $k1 = next($old1) ? key($old1) : null;
- } else {
- $l2 = $k2;
- $diff[] = current($old2);
- $k2 = next($old2) ? key($old2) : null;
- }
- }
-
- while ($idx1 < $cnt1) {
- $diff[] = sprintf("%03d- ", $idx1 + 1) . $w[$idx1++];
- }
-
- while ($idx2 < $cnt2) {
- $diff[] = sprintf("%03d+ ", $idx2 + 1) . $ar2[$idx2++];
- }
-
- return $diff;
+ $idx1 = 0;
+ $cnt1 = @count($ar1);
+ $idx2 = 0;
+ $cnt2 = @count($ar2);
+ $diff = array();
+ $old1 = array();
+ $old2 = array();
+
+ while ($idx1 < $cnt1 && $idx2 < $cnt2) {
+
+ if (comp_line($ar1[$idx1], $ar2[$idx2], $is_reg)) {
+ $idx1++;
+ $idx2++;
+ continue;
+ } else {
+
+ $c1 = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1 + 1, $idx2, $cnt1, $cnt2, 10);
+ $c2 = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $idx2 + 1, $cnt1, $cnt2, 10);
+
+ if ($c1 > $c2) {
+ $old1[$idx1] = sprintf("%03d- ", $idx1 + 1) . $w[$idx1++];
+ } else if ($c2 > 0) {
+ $old2[$idx2] = sprintf("%03d+ ", $idx2 + 1) . $ar2[$idx2++];
+ } else {
+ $old1[$idx1] = sprintf("%03d- ", $idx1 + 1) . $w[$idx1++];
+ $old2[$idx2] = sprintf("%03d+ ", $idx2 + 1) . $ar2[$idx2++];
+ }
+ }
+ }
+
+ reset($old1);
+ $k1 = key($old1);
+ $l1 = -2;
+ reset($old2);
+ $k2 = key($old2);
+ $l2 = -2;
+
+ while ($k1 !== null || $k2 !== null) {
+
+ if ($k1 == $l1 + 1 || $k2 === null) {
+ $l1 = $k1;
+ $diff[] = current($old1);
+ $k1 = next($old1) ? key($old1) : null;
+ } else if ($k2 == $l2 + 1 || $k1 === null) {
+ $l2 = $k2;
+ $diff[] = current($old2);
+ $k2 = next($old2) ? key($old2) : null;
+ } else if ($k1 < $k2) {
+ $l1 = $k1;
+ $diff[] = current($old1);
+ $k1 = next($old1) ? key($old1) : null;
+ } else {
+ $l2 = $k2;
+ $diff[] = current($old2);
+ $k2 = next($old2) ? key($old2) : null;
+ }
+ }
+
+ while ($idx1 < $cnt1) {
+ $diff[] = sprintf("%03d- ", $idx1 + 1) . $w[$idx1++];
+ }
+
+ while ($idx2 < $cnt2) {
+ $diff[] = sprintf("%03d+ ", $idx2 + 1) . $ar2[$idx2++];
+ }
+
+ return $diff;
}
function generate_diff($wanted, $wanted_re, $output)
{
- $w = explode("\n", $wanted);
- $o = explode("\n", $output);
- $r = is_null($wanted_re) ? $w : explode("\n", $wanted_re);
- $diff = generate_array_diff($r, $o, !is_null($wanted_re), $w);
+ $w = explode("\n", $wanted);
+ $o = explode("\n", $output);
+ $r = is_null($wanted_re) ? $w : explode("\n", $wanted_re);
+ $diff = generate_array_diff($r, $o, !is_null($wanted_re), $w);
- return implode(PHP_EOL, $diff);
+ return implode(PHP_EOL, $diff);
}
function error($message)
{
- echo "ERROR: {$message}\n";
- exit(1);
+ echo "ERROR: {$message}\n";
+ exit(1);
}
function settings2array($settings, &$ini_settings)
{
- foreach ($settings as $setting) {
+ foreach ($settings as $setting) {
- if (strpos($setting, '=') !== false) {
- $setting = explode("=", $setting, 2);
- $name = trim($setting[0]);
- $value = trim($setting[1]);
+ if (strpos($setting, '=') !== false) {
+ $setting = explode("=", $setting, 2);
+ $name = trim($setting[0]);
+ $value = trim($setting[1]);
- if ($name == 'extension' || $name == 'zend_extension') {
+ if ($name == 'extension' || $name == 'zend_extension') {
- if (!isset($ini_settings[$name])) {
- $ini_settings[$name] = array();
- }
+ if (!isset($ini_settings[$name])) {
+ $ini_settings[$name] = array();
+ }
- $ini_settings[$name][] = $value;
+ $ini_settings[$name][] = $value;
- } else {
- $ini_settings[$name] = $value;
- }
- }
- }
+ } else {
+ $ini_settings[$name] = $value;
+ }
+ }
+ }
}
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 (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()
{
- global $n_total, $test_results, $ignored_by_ext, $sum_results, $percent_results;
-
- $n_total = count($test_results);
- $n_total += $ignored_by_ext;
- $sum_results = array(
- 'PASSED' => 0,
- 'WARNED' => 0,
- 'SKIPPED' => 0,
- 'FAILED' => 0,
- 'BORKED' => 0,
- 'LEAKED' => 0,
- 'XFAILED' => 0,
- 'XLEAKED' => 0
- );
-
- foreach ($test_results as $v) {
- $sum_results[$v]++;
- }
-
- $sum_results['SKIPPED'] += $ignored_by_ext;
- $percent_results = array();
-
- foreach ($sum_results as $v => $n) {
- $percent_results[$v] = (100.0 * $n) / $n_total;
- }
+ global $n_total, $test_results, $ignored_by_ext, $sum_results, $percent_results;
+
+ $n_total = count($test_results);
+ $n_total += $ignored_by_ext;
+ $sum_results = array(
+ 'PASSED' => 0,
+ 'WARNED' => 0,
+ 'SKIPPED' => 0,
+ 'FAILED' => 0,
+ 'BORKED' => 0,
+ 'LEAKED' => 0,
+ 'XFAILED' => 0,
+ 'XLEAKED' => 0
+ );
+
+ foreach ($test_results as $v) {
+ $sum_results[$v]++;
+ }
+
+ $sum_results['SKIPPED'] += $ignored_by_ext;
+ $percent_results = array();
+
+ foreach ($sum_results as $v => $n) {
+ $percent_results[$v] = (100.0 * $n) / $n_total;
+ }
}
function get_summary($show_ext_summary, $show_html)
{
- global $exts_skipped, $exts_tested, $n_total, $sum_results, $percent_results, $end_time, $start_time, $failed_test_summary, $PHP_FAILED_TESTS, $valgrind;
-
- $x_total = $n_total - $sum_results['SKIPPED'] - $sum_results['BORKED'];
-
- if ($x_total) {
- $x_warned = (100.0 * $sum_results['WARNED']) / $x_total;
- $x_failed = (100.0 * $sum_results['FAILED']) / $x_total;
- $x_xfailed = (100.0 * $sum_results['XFAILED']) / $x_total;
- $x_xleaked = (100.0 * $sum_results['XLEAKED']) / $x_total;
- $x_leaked = (100.0 * $sum_results['LEAKED']) / $x_total;
- $x_passed = (100.0 * $sum_results['PASSED']) / $x_total;
- } else {
- $x_warned = $x_failed = $x_passed = $x_leaked = $x_xfailed = $x_xleaked = 0;
- }
+ global $exts_skipped, $exts_tested, $n_total, $sum_results, $percent_results, $end_time, $start_time, $failed_test_summary, $PHP_FAILED_TESTS, $valgrind;
+
+ $x_total = $n_total - $sum_results['SKIPPED'] - $sum_results['BORKED'];
+
+ if ($x_total) {
+ $x_warned = (100.0 * $sum_results['WARNED']) / $x_total;
+ $x_failed = (100.0 * $sum_results['FAILED']) / $x_total;
+ $x_xfailed = (100.0 * $sum_results['XFAILED']) / $x_total;
+ $x_xleaked = (100.0 * $sum_results['XLEAKED']) / $x_total;
+ $x_leaked = (100.0 * $sum_results['LEAKED']) / $x_total;
+ $x_passed = (100.0 * $sum_results['PASSED']) / $x_total;
+ } else {
+ $x_warned = $x_failed = $x_passed = $x_leaked = $x_xfailed = $x_xleaked = 0;
+ }
- $summary = '';
+ $summary = '';
- if ($show_html) {
- $summary .= "<pre>\n";
- }
+ if ($show_html) {
+ $summary .= "<pre>\n";
+ }
- if ($show_ext_summary) {
- $summary .= '
+ if ($show_ext_summary) {
+ $summary .= '
=====================================================================
TEST RESULT SUMMARY
---------------------------------------------------------------------
@@ -3042,17 +3042,17 @@ Exts skipped : ' . sprintf('%4d', $exts_skipped) . '
Exts tested : ' . sprintf('%4d', $exts_tested) . '
---------------------------------------------------------------------
';
- }
+ }
- $summary .= '
+ $summary .= '
Number of tests : ' . sprintf('%4d', $n_total) . ' ' . sprintf('%8d', $x_total);
- if ($sum_results['BORKED']) {
- $summary .= '
+ if ($sum_results['BORKED']) {
+ $summary .= '
Tests borked : ' . sprintf('%4d (%5.1f%%)', $sum_results['BORKED'], $percent_results['BORKED']) . ' --------';
- }
+ }
- $summary .= '
+ $summary .= '
Tests skipped : ' . sprintf('%4d (%5.1f%%)', $sum_results['SKIPPED'], $percent_results['SKIPPED']) . ' --------
Tests warned : ' . sprintf('%4d (%5.1f%%)', $sum_results['WARNED'], $percent_results['WARNED']) . ' ' . sprintf('(%5.1f%%)', $x_warned) . '
Tests failed : ' . sprintf('%4d (%5.1f%%)', $sum_results['FAILED'], $percent_results['FAILED']) . ' ' . sprintf('(%5.1f%%)', $x_failed);
@@ -3062,357 +3062,357 @@ Tests failed : ' . sprintf('%4d (%5.1f%%)', $sum_results['FAILED'], $percent_
Expected fail : ' . sprintf('%4d (%5.1f%%)', $sum_results['XFAILED'], $percent_results['XFAILED']) . ' ' . sprintf('(%5.1f%%)', $x_xfailed);
}
- if ($valgrind) {
- $summary .= '
+ if ($valgrind) {
+ $summary .= '
Tests leaked : ' . sprintf('%4d (%5.1f%%)', $sum_results['LEAKED'], $percent_results['LEAKED']) . ' ' . sprintf('(%5.1f%%)', $x_leaked);
if ($sum_results['XLEAKED']) {
$summary .= '
Expected leak : ' . sprintf('%4d (%5.1f%%)', $sum_results['XLEAKED'], $percent_results['XLEAKED']) . ' ' . sprintf('(%5.1f%%)', $x_xleaked);
}
- }
+ }
- $summary .= '
+ $summary .= '
Tests passed : ' . sprintf('%4d (%5.1f%%)', $sum_results['PASSED'], $percent_results['PASSED']) . ' ' . sprintf('(%5.1f%%)', $x_passed) . '
---------------------------------------------------------------------
Time taken : ' . sprintf('%4d seconds', $end_time - $start_time) . '
=====================================================================
';
- $failed_test_summary = '';
+ $failed_test_summary = '';
- if (count($PHP_FAILED_TESTS['SLOW'])) {
- usort($PHP_FAILED_TESTS['SLOW'], function ($a, $b) {
- return $a['info'] < $b['info'] ? 1 : -1;
- });
+ if (count($PHP_FAILED_TESTS['SLOW'])) {
+ usort($PHP_FAILED_TESTS['SLOW'], function ($a, $b) {
+ return $a['info'] < $b['info'] ? 1 : -1;
+ });
- $failed_test_summary .= '
+ $failed_test_summary .= '
=====================================================================
SLOW TEST SUMMARY
---------------------------------------------------------------------
';
- foreach ($PHP_FAILED_TESTS['SLOW'] as $failed_test_data) {
- $failed_test_summary .= sprintf('(%.3f s) ', $failed_test_data['info']) . $failed_test_data['test_name'] . "\n";
- }
- $failed_test_summary .= "=====================================================================\n";
- }
-
- if (count($PHP_FAILED_TESTS['XFAILED'])) {
- $failed_test_summary .= '
+ foreach ($PHP_FAILED_TESTS['SLOW'] as $failed_test_data) {
+ $failed_test_summary .= sprintf('(%.3f s) ', $failed_test_data['info']) . $failed_test_data['test_name'] . "\n";
+ }
+ $failed_test_summary .= "=====================================================================\n";
+ }
+
+ if (count($PHP_FAILED_TESTS['XFAILED'])) {
+ $failed_test_summary .= '
=====================================================================
EXPECTED FAILED TEST SUMMARY
---------------------------------------------------------------------
';
- foreach ($PHP_FAILED_TESTS['XFAILED'] as $failed_test_data) {
- $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
- }
- $failed_test_summary .= "=====================================================================\n";
- }
-
- if (count($PHP_FAILED_TESTS['BORKED'])) {
- $failed_test_summary .= '
+ foreach ($PHP_FAILED_TESTS['XFAILED'] as $failed_test_data) {
+ $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
+ }
+ $failed_test_summary .= "=====================================================================\n";
+ }
+
+ if (count($PHP_FAILED_TESTS['BORKED'])) {
+ $failed_test_summary .= '
=====================================================================
BORKED TEST SUMMARY
---------------------------------------------------------------------
';
- foreach ($PHP_FAILED_TESTS['BORKED'] as $failed_test_data) {
- $failed_test_summary .= $failed_test_data['info'] . "\n";
- }
+ foreach ($PHP_FAILED_TESTS['BORKED'] as $failed_test_data) {
+ $failed_test_summary .= $failed_test_data['info'] . "\n";
+ }
- $failed_test_summary .= "=====================================================================\n";
- }
+ $failed_test_summary .= "=====================================================================\n";
+ }
- if (count($PHP_FAILED_TESTS['FAILED'])) {
- $failed_test_summary .= '
+ if (count($PHP_FAILED_TESTS['FAILED'])) {
+ $failed_test_summary .= '
=====================================================================
FAILED TEST SUMMARY
---------------------------------------------------------------------
';
- foreach ($PHP_FAILED_TESTS['FAILED'] as $failed_test_data) {
- $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
- }
- $failed_test_summary .= "=====================================================================\n";
- }
- if (count($PHP_FAILED_TESTS['WARNED'])) {
- $failed_test_summary .= '
+ foreach ($PHP_FAILED_TESTS['FAILED'] as $failed_test_data) {
+ $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
+ }
+ $failed_test_summary .= "=====================================================================\n";
+ }
+ if (count($PHP_FAILED_TESTS['WARNED'])) {
+ $failed_test_summary .= '
=====================================================================
WARNED TEST SUMMARY
---------------------------------------------------------------------
';
- foreach ($PHP_FAILED_TESTS['WARNED'] as $failed_test_data) {
- $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
- }
+ foreach ($PHP_FAILED_TESTS['WARNED'] as $failed_test_data) {
+ $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
+ }
- $failed_test_summary .= "=====================================================================\n";
- }
+ $failed_test_summary .= "=====================================================================\n";
+ }
- if (count($PHP_FAILED_TESTS['LEAKED'])) {
- $failed_test_summary .= '
+ if (count($PHP_FAILED_TESTS['LEAKED'])) {
+ $failed_test_summary .= '
=====================================================================
LEAKED TEST SUMMARY
---------------------------------------------------------------------
';
- foreach ($PHP_FAILED_TESTS['LEAKED'] as $failed_test_data) {
- $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
- }
+ foreach ($PHP_FAILED_TESTS['LEAKED'] as $failed_test_data) {
+ $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
+ }
- $failed_test_summary .= "=====================================================================\n";
- }
+ $failed_test_summary .= "=====================================================================\n";
+ }
- if (count($PHP_FAILED_TESTS['XLEAKED'])) {
- $failed_test_summary .= '
+ if (count($PHP_FAILED_TESTS['XLEAKED'])) {
+ $failed_test_summary .= '
=====================================================================
EXPECTED LEAK TEST SUMMARY
---------------------------------------------------------------------
';
- foreach ($PHP_FAILED_TESTS['XLEAKED'] as $failed_test_data) {
- $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
- }
+ foreach ($PHP_FAILED_TESTS['XLEAKED'] as $failed_test_data) {
+ $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
+ }
- $failed_test_summary .= "=====================================================================\n";
- }
+ $failed_test_summary .= "=====================================================================\n";
+ }
- if ($failed_test_summary && !getenv('NO_PHPTEST_SUMMARY')) {
- $summary .= $failed_test_summary;
- }
+ if ($failed_test_summary && !getenv('NO_PHPTEST_SUMMARY')) {
+ $summary .= $failed_test_summary;
+ }
- if ($show_html) {
- $summary .= "</pre>";
- }
+ if ($show_html) {
+ $summary .= "</pre>";
+ }
- return $summary;
+ return $summary;
}
function show_start($start_time)
{
- global $html_output, $html_file;
+ global $html_output, $html_file;
- if ($html_output) {
- fwrite($html_file, "<h2>Time Start: " . date('Y-m-d H:i:s', $start_time) . "</h2>\n");
- fwrite($html_file, "<table>\n");
- }
+ if ($html_output) {
+ fwrite($html_file, "<h2>Time Start: " . date('Y-m-d H:i:s', $start_time) . "</h2>\n");
+ fwrite($html_file, "<table>\n");
+ }
- echo "TIME START " . date('Y-m-d H:i:s', $start_time) . "\n=====================================================================\n";
+ echo "TIME START " . date('Y-m-d H:i:s', $start_time) . "\n=====================================================================\n";
}
function show_end($end_time)
{
- global $html_output, $html_file;
+ global $html_output, $html_file;
- if ($html_output) {
- fwrite($html_file, "</table>\n");
- fwrite($html_file, "<h2>Time End: " . date('Y-m-d H:i:s', $end_time) . "</h2>\n");
- }
+ if ($html_output) {
+ fwrite($html_file, "</table>\n");
+ fwrite($html_file, "<h2>Time End: " . date('Y-m-d H:i:s', $end_time) . "</h2>\n");
+ }
- echo "=====================================================================\nTIME END " . date('Y-m-d H:i:s', $end_time) . "\n";
+ echo "=====================================================================\nTIME END " . date('Y-m-d H:i:s', $end_time) . "\n";
}
function show_summary()
{
- global $html_output, $html_file;
+ global $html_output, $html_file;
- if ($html_output) {
- fwrite($html_file, "<hr/>\n" . get_summary(true, true));
- }
+ if ($html_output) {
+ fwrite($html_file, "<hr/>\n" . get_summary(true, true));
+ }
- echo get_summary(true, false);
+ echo get_summary(true, false);
}
function show_redirect_start($tests, $tested, $tested_file)
{
- global $html_output, $html_file, $line_length, $SHOW_ONLY_GROUPS;
+ global $html_output, $html_file, $line_length, $SHOW_ONLY_GROUPS;
- if ($html_output) {
- fwrite($html_file, "<tr><td colspan='3'>---&gt; $tests ($tested [$tested_file]) begin</td></tr>\n");
- }
+ if ($html_output) {
+ fwrite($html_file, "<tr><td colspan='3'>---&gt; $tests ($tested [$tested_file]) begin</td></tr>\n");
+ }
- if (!$SHOW_ONLY_GROUPS || in_array('REDIRECT', $SHOW_ONLY_GROUPS)) {
- echo "REDIRECT $tests ($tested [$tested_file]) begin\n";
- } else {
- clear_show_test();
- }
+ if (!$SHOW_ONLY_GROUPS || in_array('REDIRECT', $SHOW_ONLY_GROUPS)) {
+ echo "REDIRECT $tests ($tested [$tested_file]) begin\n";
+ } else {
+ clear_show_test();
+ }
}
function show_redirect_ends($tests, $tested, $tested_file)
{
- global $html_output, $html_file, $line_length, $SHOW_ONLY_GROUPS;
+ global $html_output, $html_file, $line_length, $SHOW_ONLY_GROUPS;
- if ($html_output) {
- fwrite($html_file, "<tr><td colspan='3'>---&gt; $tests ($tested [$tested_file]) done</td></tr>\n");
- }
+ if ($html_output) {
+ fwrite($html_file, "<tr><td colspan='3'>---&gt; $tests ($tested [$tested_file]) done</td></tr>\n");
+ }
- if (!$SHOW_ONLY_GROUPS || in_array('REDIRECT', $SHOW_ONLY_GROUPS)) {
- echo "REDIRECT $tests ($tested [$tested_file]) done\n";
- } else {
- clear_show_test();
- }
+ if (!$SHOW_ONLY_GROUPS || in_array('REDIRECT', $SHOW_ONLY_GROUPS)) {
+ echo "REDIRECT $tests ($tested [$tested_file]) done\n";
+ } else {
+ clear_show_test();
+ }
}
function show_test($test_idx, $shortname)
{
- global $test_cnt;
- global $line_length;
+ global $test_cnt;
+ global $line_length;
- $str = "TEST $test_idx/$test_cnt [$shortname]\r";
- $line_length = strlen($str);
- echo $str;
- flush();
+ $str = "TEST $test_idx/$test_cnt [$shortname]\r";
+ $line_length = strlen($str);
+ echo $str;
+ flush();
}
function clear_show_test() {
- global $line_length;
- // Parallel testing
- global $workerID;
-
- if (!$workerID) {
- // Write over the last line to avoid random trailing chars on next echo
- echo str_repeat(" ", $line_length), "\r";
- }
+ global $line_length;
+ // Parallel testing
+ global $workerID;
+
+ if (!$workerID) {
+ // Write over the last line to avoid random trailing chars on next echo
+ echo str_repeat(" ", $line_length), "\r";
+ }
}
function parse_conflicts(string $text) : array {
- // Strip comments
- $text = preg_replace('/#.*/', '', $text);
- return array_map('trim', explode("\n", trim($text)));
+ // Strip comments
+ $text = preg_replace('/#.*/', '', $text);
+ return array_map('trim', explode("\n", trim($text)));
}
function show_result($result, $tested, $tested_file, $extra = '', $temp_filenames = null)
{
- global $html_output, $html_file, $temp_target, $temp_urlbase, $line_length, $SHOW_ONLY_GROUPS;
-
- if (!$SHOW_ONLY_GROUPS || in_array($result, $SHOW_ONLY_GROUPS)) {
- echo "$result $tested [$tested_file] $extra\n";
- } else if (!$SHOW_ONLY_GROUPS) {
- clear_show_test();
- }
-
- if ($html_output) {
-
- if (isset($temp_filenames['file']) && file_exists($temp_filenames['file'])) {
- $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['file']);
- $tested = "<a href='$url'>$tested</a>";
- }
-
- if (isset($temp_filenames['skip']) && file_exists($temp_filenames['skip'])) {
-
- if (empty($extra)) {
- $extra = "skipif";
- }
-
- $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['skip']);
- $extra = "<a href='$url'>$extra</a>";
-
- } else if (empty($extra)) {
- $extra = "&nbsp;";
- }
-
- if (isset($temp_filenames['diff']) && file_exists($temp_filenames['diff'])) {
- $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['diff']);
- $diff = "<a href='$url'>diff</a>";
- } else {
- $diff = "&nbsp;";
- }
-
- if (isset($temp_filenames['mem']) && file_exists($temp_filenames['mem'])) {
- $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['mem']);
- $mem = "<a href='$url'>leaks</a>";
- } else {
- $mem = "&nbsp;";
- }
-
- fwrite(
- $html_file,
- "<tr>" .
- "<td>$result</td>" .
- "<td>$tested</td>" .
- "<td>$extra</td>" .
- "<td>$diff</td>" .
- "<td>$mem</td>" .
- "</tr>\n"
- );
- }
+ global $html_output, $html_file, $temp_target, $temp_urlbase, $line_length, $SHOW_ONLY_GROUPS;
+
+ if (!$SHOW_ONLY_GROUPS || in_array($result, $SHOW_ONLY_GROUPS)) {
+ echo "$result $tested [$tested_file] $extra\n";
+ } else if (!$SHOW_ONLY_GROUPS) {
+ clear_show_test();
+ }
+
+ if ($html_output) {
+
+ if (isset($temp_filenames['file']) && file_exists($temp_filenames['file'])) {
+ $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['file']);
+ $tested = "<a href='$url'>$tested</a>";
+ }
+
+ if (isset($temp_filenames['skip']) && file_exists($temp_filenames['skip'])) {
+
+ if (empty($extra)) {
+ $extra = "skipif";
+ }
+
+ $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['skip']);
+ $extra = "<a href='$url'>$extra</a>";
+
+ } else if (empty($extra)) {
+ $extra = "&nbsp;";
+ }
+
+ if (isset($temp_filenames['diff']) && file_exists($temp_filenames['diff'])) {
+ $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['diff']);
+ $diff = "<a href='$url'>diff</a>";
+ } else {
+ $diff = "&nbsp;";
+ }
+
+ if (isset($temp_filenames['mem']) && file_exists($temp_filenames['mem'])) {
+ $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['mem']);
+ $mem = "<a href='$url'>leaks</a>";
+ } else {
+ $mem = "&nbsp;";
+ }
+
+ fwrite(
+ $html_file,
+ "<tr>" .
+ "<td>$result</td>" .
+ "<td>$tested</td>" .
+ "<td>$extra</td>" .
+ "<td>$diff</td>" .
+ "<td>$mem</td>" .
+ "</tr>\n"
+ );
+ }
}
function junit_init()
{
- // Check whether a junit log is wanted.
- global $workerID;
- $JUNIT = getenv('TEST_PHP_JUNIT');
- if (empty($JUNIT)) {
- $GLOBALS['JUNIT'] = false;
- return;
- }
- if ($workerID) {
- $fp = null;
- } else if (!$fp = fopen($JUNIT, 'w')) {
- error("Failed to open $JUNIT for writing.");
- }
- $GLOBALS['JUNIT'] = array(
- 'fp' => $fp,
- 'name' => 'PHP',
- 'test_total' => 0,
- 'test_pass' => 0,
- 'test_fail' => 0,
- 'test_error' => 0,
- 'test_skip' => 0,
- 'test_warn' => 0,
- 'execution_time' => 0,
- 'suites' => array(),
- 'files' => array()
- );
+ // Check whether a junit log is wanted.
+ global $workerID;
+ $JUNIT = getenv('TEST_PHP_JUNIT');
+ if (empty($JUNIT)) {
+ $GLOBALS['JUNIT'] = false;
+ return;
+ }
+ if ($workerID) {
+ $fp = null;
+ } else if (!$fp = fopen($JUNIT, 'w')) {
+ error("Failed to open $JUNIT for writing.");
+ }
+ $GLOBALS['JUNIT'] = array(
+ 'fp' => $fp,
+ 'name' => 'PHP',
+ 'test_total' => 0,
+ 'test_pass' => 0,
+ 'test_fail' => 0,
+ 'test_error' => 0,
+ 'test_skip' => 0,
+ 'test_warn' => 0,
+ 'execution_time' => 0,
+ 'suites' => array(),
+ 'files' => array()
+ );
}
function junit_save_xml()
{
- global $JUNIT;
- if (!junit_enabled()) return;
-
- $xml = '<' . '?' . 'xml version="1.0" encoding="UTF-8"' . '?' . '>' . PHP_EOL;
- $xml .= sprintf(
- '<testsuites name="%s" tests="%s" failures="%d" errors="%d" skip="%d" time="%s">' . PHP_EOL,
- $JUNIT['name'],
- $JUNIT['test_total'],
- $JUNIT['test_fail'],
- $JUNIT['test_error'],
- $JUNIT['test_skip'],
- $JUNIT['execution_time']
- );
- $xml .= junit_get_suite_xml();
- $xml .= '</testsuites>';
- fwrite($JUNIT['fp'], $xml);
+ global $JUNIT;
+ if (!junit_enabled()) return;
+
+ $xml = '<' . '?' . 'xml version="1.0" encoding="UTF-8"' . '?' . '>' . PHP_EOL;
+ $xml .= sprintf(
+ '<testsuites name="%s" tests="%s" failures="%d" errors="%d" skip="%d" time="%s">' . PHP_EOL,
+ $JUNIT['name'],
+ $JUNIT['test_total'],
+ $JUNIT['test_fail'],
+ $JUNIT['test_error'],
+ $JUNIT['test_skip'],
+ $JUNIT['execution_time']
+ );
+ $xml .= junit_get_suite_xml();
+ $xml .= '</testsuites>';
+ fwrite($JUNIT['fp'], $xml);
}
function junit_get_suite_xml($suite_name = '')
{
- global $JUNIT;
-
- $result = "";
-
- foreach ($JUNIT['suites'] as $suite_name => $suite) {
- $result .= sprintf(
- '<testsuite name="%s" tests="%s" failures="%d" errors="%d" skip="%d" time="%s">' . PHP_EOL,
- $suite['name'],
- $suite['test_total'],
- $suite['test_fail'],
- $suite['test_error'],
- $suite['test_skip'],
- $suite['execution_time']
- );
-
- if (!empty($suite_name)) {
- foreach ($suite['files'] as $file) {
- $result .= $JUNIT['files'][$file]['xml'];
- }
- }
-
- $result .= '</testsuite>' . PHP_EOL;
- }
-
- return $result;
+ global $JUNIT;
+
+ $result = "";
+
+ foreach ($JUNIT['suites'] as $suite_name => $suite) {
+ $result .= sprintf(
+ '<testsuite name="%s" tests="%s" failures="%d" errors="%d" skip="%d" time="%s">' . PHP_EOL,
+ $suite['name'],
+ $suite['test_total'],
+ $suite['test_fail'],
+ $suite['test_error'],
+ $suite['test_skip'],
+ $suite['execution_time']
+ );
+
+ if (!empty($suite_name)) {
+ foreach ($suite['files'] as $file) {
+ $result .= $JUNIT['files'][$file]['xml'];
+ }
+ }
+
+ $result .= '</testsuite>' . PHP_EOL;
+ }
+
+ return $result;
}
function junit_enabled()
{
- global $JUNIT;
- return !empty($JUNIT);
+ global $JUNIT;
+ return !empty($JUNIT);
}
/**
@@ -3426,253 +3426,253 @@ function junit_enabled()
*/
function junit_mark_test_as($type, $file_name, $test_name, $time = null, $message = '', $details = '')
{
- global $JUNIT;
- if (!junit_enabled()) return;
-
- $suite = junit_get_suitename_for($file_name);
-
- junit_suite_record($suite, 'test_total');
-
- $time = $time ?? junit_get_timer($file_name);
- junit_suite_record($suite, 'execution_time', $time);
-
- $escaped_details = htmlspecialchars($details, ENT_QUOTES, 'UTF-8');
- $escaped_details = preg_replace_callback('/[\0-\x08\x0B\x0C\x0E-\x1F]/', function ($c) {
- return sprintf('[[0x%02x]]', ord($c[0]));
- }, $escaped_details);
- $escaped_message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
-
- $escaped_test_name = htmlspecialchars($file_name . ' (' . $test_name . ')', ENT_QUOTES);
- $JUNIT['files'][$file_name]['xml'] = "<testcase name='$escaped_test_name' time='$time'>\n";
-
- if (is_array($type)) {
- $output_type = $type[0] . 'ED';
- $temp = array_intersect(array('XFAIL', 'XLEAK', 'FAIL', 'WARN'), $type);
- $type = reset($temp);
- } else {
- $output_type = $type . 'ED';
- }
-
- if ('PASS' == $type || 'XFAIL' == $type || 'XLEAK' == $type) {
- junit_suite_record($suite, 'test_pass');
- } elseif ('BORK' == $type) {
- junit_suite_record($suite, 'test_error');
- $JUNIT['files'][$file_name]['xml'] .= "<error type='$output_type' message='$escaped_message'/>\n";
- } elseif ('SKIP' == $type) {
- junit_suite_record($suite, 'test_skip');
- $JUNIT['files'][$file_name]['xml'] .= "<skipped>$escaped_message</skipped>\n";
- } elseif ('WARN' == $type) {
- junit_suite_record($suite, 'test_warn');
- $JUNIT['files'][$file_name]['xml'] .= "<warning>$escaped_message</warning>\n";
- } elseif ('FAIL' == $type) {
- junit_suite_record($suite, 'test_fail');
- $JUNIT['files'][$file_name]['xml'] .= "<failure type='$output_type' message='$escaped_message'>$escaped_details</failure>\n";
- } else {
- junit_suite_record($suite, 'test_error');
- $JUNIT['files'][$file_name]['xml'] .= "<error type='$output_type' message='$escaped_message'>$escaped_details</error>\n";
- }
-
- $JUNIT['files'][$file_name]['xml'] .= "</testcase>\n";
+ global $JUNIT;
+ if (!junit_enabled()) return;
+
+ $suite = junit_get_suitename_for($file_name);
+
+ junit_suite_record($suite, 'test_total');
+
+ $time = $time ?? junit_get_timer($file_name);
+ junit_suite_record($suite, 'execution_time', $time);
+
+ $escaped_details = htmlspecialchars($details, ENT_QUOTES, 'UTF-8');
+ $escaped_details = preg_replace_callback('/[\0-\x08\x0B\x0C\x0E-\x1F]/', function ($c) {
+ return sprintf('[[0x%02x]]', ord($c[0]));
+ }, $escaped_details);
+ $escaped_message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
+
+ $escaped_test_name = htmlspecialchars($file_name . ' (' . $test_name . ')', ENT_QUOTES);
+ $JUNIT['files'][$file_name]['xml'] = "<testcase name='$escaped_test_name' time='$time'>\n";
+
+ if (is_array($type)) {
+ $output_type = $type[0] . 'ED';
+ $temp = array_intersect(array('XFAIL', 'XLEAK', 'FAIL', 'WARN'), $type);
+ $type = reset($temp);
+ } else {
+ $output_type = $type . 'ED';
+ }
+
+ if ('PASS' == $type || 'XFAIL' == $type || 'XLEAK' == $type) {
+ junit_suite_record($suite, 'test_pass');
+ } elseif ('BORK' == $type) {
+ junit_suite_record($suite, 'test_error');
+ $JUNIT['files'][$file_name]['xml'] .= "<error type='$output_type' message='$escaped_message'/>\n";
+ } elseif ('SKIP' == $type) {
+ junit_suite_record($suite, 'test_skip');
+ $JUNIT['files'][$file_name]['xml'] .= "<skipped>$escaped_message</skipped>\n";
+ } elseif ('WARN' == $type) {
+ junit_suite_record($suite, 'test_warn');
+ $JUNIT['files'][$file_name]['xml'] .= "<warning>$escaped_message</warning>\n";
+ } elseif ('FAIL' == $type) {
+ junit_suite_record($suite, 'test_fail');
+ $JUNIT['files'][$file_name]['xml'] .= "<failure type='$output_type' message='$escaped_message'>$escaped_details</failure>\n";
+ } else {
+ junit_suite_record($suite, 'test_error');
+ $JUNIT['files'][$file_name]['xml'] .= "<error type='$output_type' message='$escaped_message'>$escaped_details</error>\n";
+ }
+
+ $JUNIT['files'][$file_name]['xml'] .= "</testcase>\n";
}
function junit_suite_record($suite, $param, $value = 1)
{
- global $JUNIT;
+ global $JUNIT;
- $JUNIT[$param] += $value;
- $JUNIT['suites'][$suite][$param] += $value;
+ $JUNIT[$param] += $value;
+ $JUNIT['suites'][$suite][$param] += $value;
}
function junit_get_timer($file_name)
{
- global $JUNIT;
- if (!junit_enabled()) return 0;
+ global $JUNIT;
+ if (!junit_enabled()) return 0;
- if (isset($JUNIT['files'][$file_name]['total'])) {
- return number_format($JUNIT['files'][$file_name]['total'], 4);
- }
+ if (isset($JUNIT['files'][$file_name]['total'])) {
+ return number_format($JUNIT['files'][$file_name]['total'], 4);
+ }
- return 0;
+ return 0;
}
function junit_start_timer($file_name)
{
- global $JUNIT;
- if (!junit_enabled()) return;
+ global $JUNIT;
+ if (!junit_enabled()) return;
- if (!isset($JUNIT['files'][$file_name]['start'])) {
- $JUNIT['files'][$file_name]['start'] = microtime(true);
+ if (!isset($JUNIT['files'][$file_name]['start'])) {
+ $JUNIT['files'][$file_name]['start'] = microtime(true);
- $suite = junit_get_suitename_for($file_name);
- junit_init_suite($suite);
- $JUNIT['suites'][$suite]['files'][$file_name] = $file_name;
- }
+ $suite = junit_get_suitename_for($file_name);
+ junit_init_suite($suite);
+ $JUNIT['suites'][$suite]['files'][$file_name] = $file_name;
+ }
}
function junit_get_suitename_for($file_name)
{
- return junit_path_to_classname(dirname($file_name));
+ return junit_path_to_classname(dirname($file_name));
}
function junit_path_to_classname($file_name)
{
- global $JUNIT;
-
- if (!junit_enabled()) return '';
-
- $ret = $JUNIT['name'];
- $_tmp = array();
-
- // lookup whether we're in the PHP source checkout
- $max = 5;
- if (is_file($file_name)) {
- $dir = dirname(realpath($file_name));
- } else {
- $dir = realpath($file_name);
- }
- do {
- array_unshift($_tmp, basename($dir));
- $chk = $dir . DIRECTORY_SEPARATOR . "main" . DIRECTORY_SEPARATOR . "php_version.h";
- $dir = dirname($dir);
- } while (!file_exists($chk) && --$max > 0);
- if (file_exists($chk)) {
- if ($max) {
- array_shift($_tmp);
- }
- foreach ($_tmp as $p) {
- $ret .= "." . preg_replace(",[^a-z0-9]+,i", ".", $p);
- }
- return $ret;
- }
-
- return $JUNIT['name'] . '.' . str_replace(array(DIRECTORY_SEPARATOR, '-'), '.', $file_name);
+ global $JUNIT;
+
+ if (!junit_enabled()) return '';
+
+ $ret = $JUNIT['name'];
+ $_tmp = array();
+
+ // lookup whether we're in the PHP source checkout
+ $max = 5;
+ if (is_file($file_name)) {
+ $dir = dirname(realpath($file_name));
+ } else {
+ $dir = realpath($file_name);
+ }
+ do {
+ array_unshift($_tmp, basename($dir));
+ $chk = $dir . DIRECTORY_SEPARATOR . "main" . DIRECTORY_SEPARATOR . "php_version.h";
+ $dir = dirname($dir);
+ } while (!file_exists($chk) && --$max > 0);
+ if (file_exists($chk)) {
+ if ($max) {
+ array_shift($_tmp);
+ }
+ foreach ($_tmp as $p) {
+ $ret .= "." . preg_replace(",[^a-z0-9]+,i", ".", $p);
+ }
+ return $ret;
+ }
+
+ return $JUNIT['name'] . '.' . str_replace(array(DIRECTORY_SEPARATOR, '-'), '.', $file_name);
}
function junit_init_suite($suite_name)
{
- global $JUNIT;
- if (!junit_enabled()) return;
-
- if (!empty($JUNIT['suites'][$suite_name])) {
- return;
- }
-
- $JUNIT['suites'][$suite_name] = array(
- 'name' => $suite_name,
- 'test_total' => 0,
- 'test_pass' => 0,
- 'test_fail' => 0,
- 'test_error' => 0,
- 'test_skip' => 0,
- 'test_warn' => 0,
- 'files' => array(),
- 'execution_time' => 0,
- );
+ global $JUNIT;
+ if (!junit_enabled()) return;
+
+ if (!empty($JUNIT['suites'][$suite_name])) {
+ return;
+ }
+
+ $JUNIT['suites'][$suite_name] = array(
+ 'name' => $suite_name,
+ 'test_total' => 0,
+ 'test_pass' => 0,
+ 'test_fail' => 0,
+ 'test_error' => 0,
+ 'test_skip' => 0,
+ 'test_warn' => 0,
+ 'files' => array(),
+ 'execution_time' => 0,
+ );
}
function junit_finish_timer($file_name)
{
- global $JUNIT;
- if (!junit_enabled()) return;
+ global $JUNIT;
+ if (!junit_enabled()) return;
- if (!isset($JUNIT['files'][$file_name]['start'])) {
- error("Timer for $file_name was not started!");
- }
+ if (!isset($JUNIT['files'][$file_name]['start'])) {
+ error("Timer for $file_name was not started!");
+ }
- if (!isset($JUNIT['files'][$file_name]['total'])) {
- $JUNIT['files'][$file_name]['total'] = 0;
- }
+ if (!isset($JUNIT['files'][$file_name]['total'])) {
+ $JUNIT['files'][$file_name]['total'] = 0;
+ }
- $start = $JUNIT['files'][$file_name]['start'];
- $JUNIT['files'][$file_name]['total'] += microtime(true) - $start;
- unset($JUNIT['files'][$file_name]['start']);
+ $start = $JUNIT['files'][$file_name]['start'];
+ $JUNIT['files'][$file_name]['total'] += microtime(true) - $start;
+ unset($JUNIT['files'][$file_name]['start']);
}
function junit_merge_results($junit)
{
- global $JUNIT;
- $JUNIT['test_total'] += $junit['test_total'];
- $JUNIT['test_pass'] += $junit['test_pass'];
- $JUNIT['test_fail'] += $junit['test_fail'];
- $JUNIT['test_error'] += $junit['test_error'];
- $JUNIT['test_skip'] += $junit['test_skip'];
- $JUNIT['test_warn'] += $junit['test_warn'];
- $JUNIT['execution_time'] += $junit['execution_time'];
- $JUNIT['files'] += $junit['files'];
- foreach ($junit['suites'] as $name => $suite) {
- if (!isset($JUNIT['suites'][$name])) {
- $JUNIT['suites'][$name] = $suite;
- continue;
- }
-
- $SUITE =& $JUNIT['suites'][$name];
- $SUITE['test_total'] += $suite['test_total'];
- $SUITE['test_pass'] += $suite['test_pass'];
- $SUITE['test_fail'] += $suite['test_fail'];
- $SUITE['test_error'] += $suite['test_error'];
- $SUITE['test_skip'] += $suite['test_skip'];
- $SUITE['test_warn'] += $suite['test_warn'];
- $SUITE['execution_time'] += $suite['execution_time'];
- $SUITE['files'] += $suite['files'];
- }
+ global $JUNIT;
+ $JUNIT['test_total'] += $junit['test_total'];
+ $JUNIT['test_pass'] += $junit['test_pass'];
+ $JUNIT['test_fail'] += $junit['test_fail'];
+ $JUNIT['test_error'] += $junit['test_error'];
+ $JUNIT['test_skip'] += $junit['test_skip'];
+ $JUNIT['test_warn'] += $junit['test_warn'];
+ $JUNIT['execution_time'] += $junit['execution_time'];
+ $JUNIT['files'] += $junit['files'];
+ foreach ($junit['suites'] as $name => $suite) {
+ if (!isset($JUNIT['suites'][$name])) {
+ $JUNIT['suites'][$name] = $suite;
+ continue;
+ }
+
+ $SUITE =& $JUNIT['suites'][$name];
+ $SUITE['test_total'] += $suite['test_total'];
+ $SUITE['test_pass'] += $suite['test_pass'];
+ $SUITE['test_fail'] += $suite['test_fail'];
+ $SUITE['test_error'] += $suite['test_error'];
+ $SUITE['test_skip'] += $suite['test_skip'];
+ $SUITE['test_warn'] += $suite['test_warn'];
+ $SUITE['execution_time'] += $suite['execution_time'];
+ $SUITE['files'] += $suite['files'];
+ }
}
class RuntestsValgrind
{
- protected $version = '';
- protected $header = '';
- protected $version_3_3_0 = false;
- protected $version_3_8_0 = false;
- protected $tool = null;
-
- public function getVersion()
- {
- return $this->version;
- }
-
- public function getHeader()
- {
- return $this->header;
- }
-
- public function __construct(array $environment, string $tool = 'memcheck')
- {
- $this->tool = $tool;
- $header = system_with_timeout("valgrind --tool={$this->tool} --version", $environment);
- if (!$header) {
- error("Valgrind returned no version info for {$this->tool}, cannot proceed.\n".
+ protected $version = '';
+ protected $header = '';
+ protected $version_3_3_0 = false;
+ protected $version_3_8_0 = false;
+ protected $tool = null;
+
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ public function getHeader()
+ {
+ return $this->header;
+ }
+
+ public function __construct(array $environment, string $tool = 'memcheck')
+ {
+ $this->tool = $tool;
+ $header = system_with_timeout("valgrind --tool={$this->tool} --version", $environment);
+ if (!$header) {
+ error("Valgrind returned no version info for {$this->tool}, cannot proceed.\n".
"Please check if Valgrind is installed and the tool is named correctly.");
- }
- $count = 0;
- $version = preg_replace("/valgrind-(\d+)\.(\d+)\.(\d+)([.\w_-]+)?(\s+)/", '$1.$2.$3', $header, 1, $count);
- if ($count != 1) {
- error("Valgrind returned invalid version info (\"{$header}\") for {$this->tool}, cannot proceed.");
- }
- $this->version = $version;
- $this->header = sprintf(
- "%s (%s)", trim($header), $this->tool);
- $this->version_3_3_0 = version_compare($version, '3.3.0', '>=');
- $this->version_3_8_0 = version_compare($version, '3.8.0', '>=');
- }
-
- public function wrapCommand($cmd, $memcheck_filename, $check_all)
- {
- $vcmd = "valgrind -q --tool={$this->tool} --trace-children=yes";
- if ($check_all) {
- $vcmd .= ' --smc-check=all';
- }
-
- /* --vex-iropt-register-updates=allregs-at-mem-access is necessary for phpdbg watchpoint tests */
- if ($this->version_3_8_0) {
- /* valgrind 3.3.0+ doesn't have --log-file-exactly option */
- return "$vcmd --vex-iropt-register-updates=allregs-at-mem-access --log-file=$memcheck_filename $cmd";
- } elseif ($this->version_3_3_0) {
- return "$vcmd --vex-iropt-precise-memory-exns=yes --log-file=$memcheck_filename $cmd";
- } else {
- return "$vcmd --vex-iropt-precise-memory-exns=yes --log-file-exactly=$memcheck_filename $cmd";
- }
- }
+ }
+ $count = 0;
+ $version = preg_replace("/valgrind-(\d+)\.(\d+)\.(\d+)([.\w_-]+)?(\s+)/", '$1.$2.$3', $header, 1, $count);
+ if ($count != 1) {
+ error("Valgrind returned invalid version info (\"{$header}\") for {$this->tool}, cannot proceed.");
+ }
+ $this->version = $version;
+ $this->header = sprintf(
+ "%s (%s)", trim($header), $this->tool);
+ $this->version_3_3_0 = version_compare($version, '3.3.0', '>=');
+ $this->version_3_8_0 = version_compare($version, '3.8.0', '>=');
+ }
+
+ public function wrapCommand($cmd, $memcheck_filename, $check_all)
+ {
+ $vcmd = "valgrind -q --tool={$this->tool} --trace-children=yes";
+ if ($check_all) {
+ $vcmd .= ' --smc-check=all';
+ }
+
+ /* --vex-iropt-register-updates=allregs-at-mem-access is necessary for phpdbg watchpoint tests */
+ if ($this->version_3_8_0) {
+ /* valgrind 3.3.0+ doesn't have --log-file-exactly option */
+ return "$vcmd --vex-iropt-register-updates=allregs-at-mem-access --log-file=$memcheck_filename $cmd";
+ } elseif ($this->version_3_3_0) {
+ return "$vcmd --vex-iropt-precise-memory-exns=yes --log-file=$memcheck_filename $cmd";
+ } else {
+ return "$vcmd --vex-iropt-precise-memory-exns=yes --log-file-exactly=$memcheck_filename $cmd";
+ }
+ }
}
main();
diff --git a/sapi/cli/generate_mime_type_map.php b/sapi/cli/generate_mime_type_map.php
index a4504500c0..c4c83679c2 100755
--- a/sapi/cli/generate_mime_type_map.php
+++ b/sapi/cli/generate_mime_type_map.php
@@ -8,36 +8,36 @@ $source = count($_SERVER['argv']) > 1 ? $_SERVER['argv'][1] : 'https://raw.githu
// See if we can actually load it.
$types = @file($source);
if ($types === false) {
- fprintf(STDERR, "Error: unable to read $source\n");
- exit(1);
+ fprintf(STDERR, "Error: unable to read $source\n");
+ exit(1);
}
// Remove comments and flip into an extensions array.
$extensions = [];
array_walk($types, function ($line) use (&$extensions) {
- $line = trim($line);
- if ($line && $line[0] != '#') {
- $fields = preg_split('/\s+/', $line);
- if (count($fields) > 1) {
- $mime = array_shift($fields);
- foreach ($fields as $extension) {
- $extensions[$extension] = $mime;
- }
- }
- }
+ $line = trim($line);
+ if ($line && $line[0] != '#') {
+ $fields = preg_split('/\s+/', $line);
+ if (count($fields) > 1) {
+ $mime = array_shift($fields);
+ foreach ($fields as $extension) {
+ $extensions[$extension] = $mime;
+ }
+ }
+ }
});
$additional_mime_maps = [
- "map" => "application/json", // from commit: a0d62f08ae8cbebc88e5c92e08fca8d0cdc7309d
- "jsm" => "application/javascript",
+ "map" => "application/json", // from commit: a0d62f08ae8cbebc88e5c92e08fca8d0cdc7309d
+ "jsm" => "application/javascript",
];
foreach($additional_mime_maps as $ext => $mime) {
- if (!isset($extensions[$ext])) {
- $extensions[$ext] = $mime;
- } else {
- printf(STDERR, "Ignored exist mime type: $ext => $mime\n");
- }
+ if (!isset($extensions[$ext])) {
+ $extensions[$ext] = $mime;
+ } else {
+ printf(STDERR, "Ignored exist mime type: $ext => $mime\n");
+ }
}
?>
@@ -64,15 +64,15 @@ foreach($additional_mime_maps as $ext => $mime) {
#define PHP_CLI_SERVER_MIME_TYPE_MAP_H
typedef struct php_cli_server_ext_mime_type_pair {
- const char *ext;
- const char *mime_type;
+ const char *ext;
+ const char *mime_type;
} php_cli_server_ext_mime_type_pair;
static const php_cli_server_ext_mime_type_pair mime_type_map[] = {
<?php foreach ($extensions as $extension => $mime): ?>
- { "<?= addcslashes($extension, "\0..\37!@\@\177..\377") ?>", "<?= addcslashes($mime, "\0..\37!@\@\177..\377") ?>" },
+ { "<?= addcslashes($extension, "\0..\37!@\@\177..\377") ?>", "<?= addcslashes($mime, "\0..\37!@\@\177..\377") ?>" },
<?php endforeach ?>
- { NULL, NULL }
+ { NULL, NULL }
};
#endif /* PHP_CLI_SERVER_MIME_TYPE_MAP_H */
diff --git a/sapi/phpdbg/create-test.php b/sapi/phpdbg/create-test.php
index 3cba7d42b0..06fb7e1632 100755
--- a/sapi/phpdbg/create-test.php
+++ b/sapi/phpdbg/create-test.php
@@ -30,37 +30,37 @@ $file = "";
$cmdargv = "";
if (isset($argc) && $argc > 1) {
- $post_ddash = false;
- for ($i = 1; $i < $argc; $i++) {
- if ($argv[$i][0] == "-" && !$post_ddash) {
- switch (substr($argv[$i], 1)) {
- case "p":
- $phpdbg = $argv[++$i];
- break;
- case "n":
- $pass_options .= " -n";
- break;
- case "d":
- $pass_options .= " -d ".escapeshellarg($argv[++$i]);
- $ini[] = $argv[$i];
- break;
- case "-":
- $post_ddash = true;
- break;
- }
- } else {
- $real_argv[] = $argv[$i];
- }
- }
- if (isset($real_argv[0])) {
- $file = realpath($real_argv[0]);
- $cmdargv = implode(" ", array_map("escapeshellarg", array_slice($real_argv, 1)));
- }
+ $post_ddash = false;
+ for ($i = 1; $i < $argc; $i++) {
+ if ($argv[$i][0] == "-" && !$post_ddash) {
+ switch (substr($argv[$i], 1)) {
+ case "p":
+ $phpdbg = $argv[++$i];
+ break;
+ case "n":
+ $pass_options .= " -n";
+ break;
+ case "d":
+ $pass_options .= " -d ".escapeshellarg($argv[++$i]);
+ $ini[] = $argv[$i];
+ break;
+ case "-":
+ $post_ddash = true;
+ break;
+ }
+ } else {
+ $real_argv[] = $argv[$i];
+ }
+ }
+ if (isset($real_argv[0])) {
+ $file = realpath($real_argv[0]);
+ $cmdargv = implode(" ", array_map("escapeshellarg", array_slice($real_argv, 1)));
+ }
}
$proc = proc_open("$phpdbg $pass_options $file -- $cmdargv", [["pipe", "r"], ["pipe", "w"], ["pipe", "w"]], $pipes);
if (!$proc) {
- die("Couldn't start phpdbg\n");
+ die("Couldn't start phpdbg\n");
}
$input = $output = "";
@@ -68,47 +68,47 @@ $input = $output = "";
stream_set_blocking(STDIN, false);
do {
- $r = [$pipes[1], STDIN];
- $w = $e = null;
- $n = @stream_select($r, $w, $e, null);
-
- if ($n > 0) {
- if ("" != $in = fread(STDIN, 1024)) {
- $input .= $in;
- fwrite($pipes[0], $in);
- continue;
- }
-
- if (feof(STDIN)) {
- die("stdin closed?!\n");
- }
-
- if (feof($pipes[1])) {
- $n = false;
- } else {
- $output .= $c = fgetc($pipes[1]);
- echo $c;
- }
- }
+ $r = [$pipes[1], STDIN];
+ $w = $e = null;
+ $n = @stream_select($r, $w, $e, null);
+
+ if ($n > 0) {
+ if ("" != $in = fread(STDIN, 1024)) {
+ $input .= $in;
+ fwrite($pipes[0], $in);
+ continue;
+ }
+
+ if (feof(STDIN)) {
+ die("stdin closed?!\n");
+ }
+
+ if (feof($pipes[1])) {
+ $n = false;
+ } else {
+ $output .= $c = fgetc($pipes[1]);
+ echo $c;
+ }
+ }
} while ($n !== false);
stream_set_blocking(STDIN, true);
print "\n";
if (!isset($name)) {
- print "Specify the test description: ";
- $desc = trim(fgets(STDIN));
+ print "Specify the test description: ";
+ $desc = trim(fgets(STDIN));
}
while (!isset($testfile)) {
- print "Specify the test file name (leave empty to write to stderr): ";
- $testfile = trim(fgets(STDIN));
- if ($testfile != "" && file_exists($testfile)) {
- print "That file already exists. Type y or yes to overwrite: ";
- $y = trim(fgets(STDIN));
- if ($y !== "y" && $y !== "yes") {
- unset($testfile);
- }
- }
+ print "Specify the test file name (leave empty to write to stderr): ";
+ $testfile = trim(fgets(STDIN));
+ if ($testfile != "" && file_exists($testfile)) {
+ print "That file already exists. Type y or yes to overwrite: ";
+ $y = trim(fgets(STDIN));
+ if ($y !== "y" && $y !== "yes") {
+ unset($testfile);
+ }
+ }
}
$output = str_replace("string(".strlen($file).") \"$file\"", 'string(%d) "%s"', $output);
@@ -125,24 +125,24 @@ $output
TEST;
if (!empty($ini)) {
- $testdata .= "\n--INI--\n".implode("\n", $ini);
+ $testdata .= "\n--INI--\n".implode("\n", $ini);
}
if ($cmdargv != "") {
- $testdata .= "\n--ARGS--\n$cmdargv";
+ $testdata .= "\n--ARGS--\n$cmdargv";
}
if ($file != "") {
- $testdata .= "\n--FILE--\n".file_get_contents($file);
+ $testdata .= "\n--FILE--\n".file_get_contents($file);
}
if ($testfile == "") {
- print "\n";
+ print "\n";
} elseif (file_put_contents($testfile, $testdata)) {
- print "Test saved to $testfile\n";
+ print "Test saved to $testfile\n";
} else {
- print "The test could not be saved to $testfile; outputting on stderr now\n";
- $testfile = "";
+ print "The test could not be saved to $testfile; outputting on stderr now\n";
+ $testfile = "";
}
if ($testfile == "") {
- fwrite(STDERR, $testdata);
+ fwrite(STDERR, $testdata);
}
diff --git a/sapi/phpdbg/phpdbg_bp.c b/sapi/phpdbg/phpdbg_bp.c
index f3c453f7d3..e6b7c10225 100644
--- a/sapi/phpdbg/phpdbg_bp.c
+++ b/sapi/phpdbg/phpdbg_bp.c
@@ -196,19 +196,19 @@ PHPDBG_API void phpdbg_export_breakpoints_to_string(char **str) /* {{{ */
"%sbreak at %s#%ld if %s\n",
*str, conditional->param.str, conditional->param.num, conditional->code);
break;
-
+
case NUMERIC_METHOD_PARAM:
phpdbg_asprintf(&new_str,
"%sbreak at %s::%s#%ld if %s\n",
*str, conditional->param.method.class, conditional->param.method.name, conditional->param.num, conditional->code);
break;
-
+
case ADDR_PARAM:
phpdbg_asprintf(&new_str,
"%sbreak at 0X%lx if %s\n",
*str, conditional->param.addr, conditional->code);
break;
-
+
case STR_PARAM:
phpdbg_asprintf(&new_str,
"%sbreak at %s if %s\n", *str, conditional->param.str, conditional->code);
@@ -839,7 +839,7 @@ static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, co
case ADDR_PARAM:
/* do nothing */
break;
-
+
default:
phpdbg_error("eval", "type=\"invalidparameter\"", "Invalid parameter type for conditional breakpoint");
return;
@@ -855,10 +855,10 @@ static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, co
if (new_break.param.type == FILE_PARAM ||
new_break.param.type == NUMERIC_FILE_PARAM) {
char realpath[MAXPATHLEN];
-
+
if (VCWD_REALPATH(new_break.param.file.name, realpath)) {
efree(new_break.param.file.name);
-
+
new_break.param.file.name = estrdup(realpath);
} else {
phpdbg_error("eval", "type=\"invalidparameter\"", "Invalid file for conditional break %s", new_break.param.file.name);
diff --git a/sapi/phpdbg/test.php b/sapi/phpdbg/test.php
index d93c81a89a..265ea9697c 100644
--- a/sapi/phpdbg/test.php
+++ b/sapi/phpdbg/test.php
@@ -1,35 +1,35 @@
<?php
if (isset($include)) {
- include (sprintf("%s/web-bootstrap.php", dirname(__FILE__)));
+ include (sprintf("%s/web-bootstrap.php", dirname(__FILE__)));
}
$stdout = fopen("php://stdout", "w+");
class phpdbg {
- private $sprintf = "%s: %s\n";
+ private $sprintf = "%s: %s\n";
- public function isGreat($greeting = null) {
- printf($this->sprintf, __METHOD__, $greeting);
- return $this;
- }
+ public function isGreat($greeting = null) {
+ printf($this->sprintf, __METHOD__, $greeting);
+ return $this;
+ }
}
function mine() {
- var_dump(func_get_args());
+ var_dump(func_get_args());
}
function test($x, $y = 0) {
- $var = $x + 1;
- $var += 2;
- $var <<= 3;
+ $var = $x + 1;
+ $var += 2;
+ $var <<= 3;
- $foo = function () {
- echo "bar!\n";
- };
+ $foo = function () {
+ echo "bar!\n";
+ };
- $foo();
+ $foo();
- yield $var;
+ yield $var;
}
$dbg = new phpdbg();
@@ -38,43 +38,43 @@ var_dump(
$dbg->isGreat("PHP Rocks!!"));
foreach (test(1,2) as $gen)
- continue;
+ continue;
echo "it works!\n";
if (isset($dump))
- var_dump($_SERVER);
+ var_dump($_SERVER);
function phpdbg_test_ob()
{
- echo 'Start';
- ob_start();
- echo 'Hello';
- $b = ob_get_clean();
- echo 'End';
- echo $b;
+ echo 'Start';
+ ob_start();
+ echo 'Hello';
+ $b = ob_get_clean();
+ echo 'End';
+ echo $b;
}
$array = [
- 1,
- 2,
- [3, 4],
- [5, 6],
+ 1,
+ 2,
+ [3, 4],
+ [5, 6],
];
$array[] = 7;
array_walk($array, function (&$item) {
- if (is_array($item))
- $item[0] += 2;
- else
- $item -= 1;
+ if (is_array($item))
+ $item[0] += 2;
+ else
+ $item -= 1;
});
class testClass {
- public $a = 2;
- protected $b = [1, 3];
- private $c = 7;
+ public $a = 2;
+ protected $b = [1, 3];
+ private $c = 7;
}
$obj = new testClass;
diff --git a/scripts/dev/check_parameters.php b/scripts/dev/check_parameters.php
index 47b0affacf..52424def1e 100755
--- a/scripts/dev/check_parameters.php
+++ b/scripts/dev/check_parameters.php
@@ -29,349 +29,349 @@ ini_set('pcre.backtrack_limit', 10000000);
$API_params = array(
- 'a' => array('zval**'), // array
- 'A' => array('zval**'), // array or object
- 'b' => array('zend_bool*'), // boolean
- 'd' => array('double*'), // double
- 'f' => array('zend_fcall_info*', 'zend_fcall_info_cache*'), // function
- 'h' => array('HashTable**'), // array as an HashTable*
- 'H' => array('HashTable**'), // array or HASH_OF(object)
- 'l' => array('zend_long*'), // long
- //TODO 'L' => array('zend_long*, '), // long
- 'o' => array('zval**'), //object
- 'O' => array('zval**', 'zend_class_entry*'), // object of given type
- 'P' => array('zend_string**'), // valid path
- 'r' => array('zval**'), // resource
- 'S' => array('zend_string**'), // string
- 'z' => array('zval**'), // zval*
- 'Z' => array('zval***') // zval**
- // 's', 'p', 'C' handled separately
+ 'a' => array('zval**'), // array
+ 'A' => array('zval**'), // array or object
+ 'b' => array('zend_bool*'), // boolean
+ 'd' => array('double*'), // double
+ 'f' => array('zend_fcall_info*', 'zend_fcall_info_cache*'), // function
+ 'h' => array('HashTable**'), // array as an HashTable*
+ 'H' => array('HashTable**'), // array or HASH_OF(object)
+ 'l' => array('zend_long*'), // long
+ //TODO 'L' => array('zend_long*, '), // long
+ 'o' => array('zval**'), //object
+ 'O' => array('zval**', 'zend_class_entry*'), // object of given type
+ 'P' => array('zend_string**'), // valid path
+ 'r' => array('zval**'), // resource
+ 'S' => array('zend_string**'), // string
+ 'z' => array('zval**'), // zval*
+ 'Z' => array('zval***') // zval**
+ // 's', 'p', 'C' handled separately
);
/** reports an error, according to its level */
function error($str, $level = 0)
{
- global $current_file, $current_function, $line;
-
- if ($level <= REPORT_LEVEL) {
- if (strpos($current_file,PHPDIR) === 0) {
- $filename = substr($current_file, strlen(PHPDIR)+1);
- } else {
- $filename = $current_file;
- }
- echo $filename , " [$line] $current_function : $str\n";
- }
+ global $current_file, $current_function, $line;
+
+ if ($level <= REPORT_LEVEL) {
+ if (strpos($current_file,PHPDIR) === 0) {
+ $filename = substr($current_file, strlen(PHPDIR)+1);
+ } else {
+ $filename = $current_file;
+ }
+ echo $filename , " [$line] $current_function : $str\n";
+ }
}
/** this updates the global var $line (for error reporting) */
function update_lineno($offset)
{
- global $lines_offset, $line;
-
- $left = 0;
- $right = $count = count($lines_offset)-1;
-
- // a nice binary search :)
- do {
- $mid = intval(($left + $right)/2);
- $val = $lines_offset[$mid];
-
- if ($val < $offset) {
- if (++$mid > $count || $lines_offset[$mid] > $offset) {
- $line = $mid;
- return;
- } else {
- $left = $mid;
- }
- } else if ($val > $offset) {
- if ($lines_offset[--$mid] < $offset) {
- $line = $mid+1;
- return;
- } else {
- $right = $mid;
- }
- } else {
- $line = $mid+1;
- return;
- }
- } while (true);
+ global $lines_offset, $line;
+
+ $left = 0;
+ $right = $count = count($lines_offset)-1;
+
+ // a nice binary search :)
+ do {
+ $mid = intval(($left + $right)/2);
+ $val = $lines_offset[$mid];
+
+ if ($val < $offset) {
+ if (++$mid > $count || $lines_offset[$mid] > $offset) {
+ $line = $mid;
+ return;
+ } else {
+ $left = $mid;
+ }
+ } else if ($val > $offset) {
+ if ($lines_offset[--$mid] < $offset) {
+ $line = $mid+1;
+ return;
+ } else {
+ $right = $mid;
+ }
+ } else {
+ $line = $mid+1;
+ return;
+ }
+ } while (true);
}
/** parses the sources and fetches its vars name, type and if they are initialized or not */
function get_vars($txt)
{
- $ret = array();
- preg_match_all('/((?:(?:unsigned|struct)\s+)?\w+)(?:\s*(\*+)\s+|\s+(\**))(\w+(?:\[\s*\w*\s*\])?)\s*(?:(=)[^,;]+)?((?:\s*,\s*\**\s*\w+(?:\[\s*\w*\s*\])?\s*(?:=[^,;]+)?)*)\s*;/S', $txt, $m, PREG_SET_ORDER);
-
- foreach ($m as $x) {
- // the first parameter is special
- if (!in_array($x[1], array('else', 'endif', 'return'))) // hack to skip reserved words
- $ret[$x[4]] = array($x[1] . $x[2] . $x[3], $x[5]);
-
- // are there more vars?
- if ($x[6]) {
- preg_match_all('/(\**)\s*(\w+(?:\[\s*\w*\s*\])?)\s*(=?)/S', $x[6], $y, PREG_SET_ORDER);
- foreach ($y as $z) {
- $ret[$z[2]] = array($x[1] . $z[1], $z[3]);
- }
- }
- }
+ $ret = array();
+ preg_match_all('/((?:(?:unsigned|struct)\s+)?\w+)(?:\s*(\*+)\s+|\s+(\**))(\w+(?:\[\s*\w*\s*\])?)\s*(?:(=)[^,;]+)?((?:\s*,\s*\**\s*\w+(?:\[\s*\w*\s*\])?\s*(?:=[^,;]+)?)*)\s*;/S', $txt, $m, PREG_SET_ORDER);
+
+ foreach ($m as $x) {
+ // the first parameter is special
+ if (!in_array($x[1], array('else', 'endif', 'return'))) // hack to skip reserved words
+ $ret[$x[4]] = array($x[1] . $x[2] . $x[3], $x[5]);
+
+ // are there more vars?
+ if ($x[6]) {
+ preg_match_all('/(\**)\s*(\w+(?:\[\s*\w*\s*\])?)\s*(=?)/S', $x[6], $y, PREG_SET_ORDER);
+ foreach ($y as $z) {
+ $ret[$z[2]] = array($x[1] . $z[1], $z[3]);
+ }
+ }
+ }
// if ($GLOBALS['current_function'] == 'for_debugging') { print_r($m);print_r($ret); }
- return $ret;
+ return $ret;
}
/** run diagnostic checks against one var. */
function check_param($db, $idx, $exp, $optional, $allow_uninit = false)
{
- global $error_few_vars_given;
-
- if ($idx >= count($db)) {
- if (!$error_few_vars_given) {
- error("too few variables passed to function");
- $error_few_vars_given = true;
- }
- return;
- } elseif ($db[$idx][0] === '**dummy**') {
- return;
- }
-
- if ($db[$idx][1] != $exp) {
- error("{$db[$idx][0]}: expected '$exp' but got '{$db[$idx][1]}' [".($idx+1).']');
- }
-
- if (!$optional && $db[$idx][2]) {
- error("not optional var is initialized: {$db[$idx][0]} [".($idx+1).']', 2);
- }
- if (!$allow_uninit && $optional && !$db[$idx][2]) {
- error("optional var not initialized: {$db[$idx][0]} [".($idx+1).']', 1);
- }
+ global $error_few_vars_given;
+
+ if ($idx >= count($db)) {
+ if (!$error_few_vars_given) {
+ error("too few variables passed to function");
+ $error_few_vars_given = true;
+ }
+ return;
+ } elseif ($db[$idx][0] === '**dummy**') {
+ return;
+ }
+
+ if ($db[$idx][1] != $exp) {
+ error("{$db[$idx][0]}: expected '$exp' but got '{$db[$idx][1]}' [".($idx+1).']');
+ }
+
+ if (!$optional && $db[$idx][2]) {
+ error("not optional var is initialized: {$db[$idx][0]} [".($idx+1).']', 2);
+ }
+ if (!$allow_uninit && $optional && !$db[$idx][2]) {
+ error("optional var not initialized: {$db[$idx][0]} [".($idx+1).']', 1);
+ }
}
/** fetch params passed to zend_parse_params*() */
function get_params($vars, $str)
{
- $ret = array();
- preg_match_all('/(?:\([^)]+\))?(&?)([\w>.()-]+(?:\[\w+\])?)\s*,?((?:\)*\s*=)?)/S', $str, $m, PREG_SET_ORDER);
+ $ret = array();
+ preg_match_all('/(?:\([^)]+\))?(&?)([\w>.()-]+(?:\[\w+\])?)\s*,?((?:\)*\s*=)?)/S', $str, $m, PREG_SET_ORDER);
- foreach ($m as $x) {
- $name = $x[2];
+ foreach ($m as $x) {
+ $name = $x[2];
- // little hack for last parameter
- if (strpos($name, '(') === false) {
- $name = rtrim($name, ')');
- }
+ // little hack for last parameter
+ if (strpos($name, '(') === false) {
+ $name = rtrim($name, ')');
+ }
- if (empty($vars[$name][0])) {
- error("variable not found: '$name'", 3);
- $ret[][] = '**dummy**';
+ if (empty($vars[$name][0])) {
+ error("variable not found: '$name'", 3);
+ $ret[][] = '**dummy**';
- } else {
- $ret[] = array($name, $vars[$name][0] . ($x[1] ? '*' : ''), $vars[$name][1]);
- }
+ } else {
+ $ret[] = array($name, $vars[$name][0] . ($x[1] ? '*' : ''), $vars[$name][1]);
+ }
- // the end (yes, this is a little hack :P)
- if ($x[3]) {
- break;
- }
- }
+ // the end (yes, this is a little hack :P)
+ if ($x[3]) {
+ break;
+ }
+ }
// if ($GLOBALS['current_function'] == 'for_debugging') { var_dump($m); var_dump($ret); }
- return $ret;
+ return $ret;
}
/** run tests on a function. the code is passed in $txt */
function check_function($name, $txt, $offset)
{
- global $API_params;
-
- $regex = '/
- (?: zend_parse_parameters(?:_throw)? \s*\([^,]+
- | zend_parse_(?:parameters_ex|method_parameters) \s*\([^,]+,[^,]+
- | zend_parse_method_parameters_ex \s*\([^,]+,[^,]+,[^,+]
- )
- ,\s*"([^"]*)"\s*
- ,\s*([^{;]*)
- /Sx';
- if (preg_match_all($regex, $txt, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
-
- $GLOBALS['current_function'] = $name;
-
- foreach ($matches as $m) {
- $GLOBALS['error_few_vars_given'] = false;
- update_lineno($offset + $m[2][1]);
-
- $vars = get_vars(substr($txt, 0, $m[0][1])); // limit var search to current location
- $params = get_params($vars, $m[2][0]);
- $optional = $varargs = false;
- $last_char = '';
- $j = -1;
-
- $spec = $m[1][0];
- $len = strlen($spec);
- for ($i = 0; $i < $len; ++$i) {
- $char = $spec[$i];
- switch ($char = $spec[$i]) {
- // separator for optional parameters
- case '|':
- if ($optional) {
- error("more than one optional separator at char #$i");
- } else {
- $optional = true;
- if ($i == $len-1) {
- error("unnecessary optional separator");
- }
- }
- break;
-
- // separate_zval_if_not_ref
- case '/':
- if (in_array($last_char, array('l', 'L', 'd', 'b'))) {
- error("the '/' specifier should not be applied to '$last_char'");
- }
- break;
-
- // nullable arguments
- case '!':
- if (in_array($last_char, array('l', 'L', 'd', 'b'))) {
- check_param($params, ++$j, 'zend_bool*', $optional);
- }
- break;
-
- // variadic arguments
- case '+':
- case '*':
- if ($varargs) {
- error("A varargs specifier can only be used once. repeated char at column $i");
- } else {
- check_param($params, ++$j, 'zval**', $optional);
- check_param($params, ++$j, 'int*', $optional);
- $varargs = true;
- }
- break;
-
- case 's':
- case 'p':
- check_param($params, ++$j, 'char**', $optional, $allow_uninit=true);
- check_param($params, ++$j, 'size_t*', $optional, $allow_uninit=true);
- if ($optional && !$params[$j-1][2] && !$params[$j][2]
- && $params[$j-1][0] !== '**dummy**' && $params[$j][0] !== '**dummy**') {
- error("one of optional vars {$params[$j-1][0]} or {$params[$j][0]} must be initialized", 1);
- }
- break;
-
- case 'C':
- // C must always be initialized, independently of whether it's optional
- check_param($params, ++$j, 'zend_class_entry**', false);
- break;
-
- default:
- if (!isset($API_params[$char])) {
- error("unknown char ('$char') at column $i");
- }
-
- // If an is_null flag is in use, only that flag is required to be
- // initialized
- $allow_uninit = $i+1 < $len && $spec[$i+1] === '!'
- && in_array($char, array('l', 'L', 'd', 'b'));
-
- foreach ($API_params[$char] as $exp) {
- check_param($params, ++$j, $exp, $optional, $allow_uninit);
- }
- }
-
- $last_char = $char;
- }
- }
- }
+ global $API_params;
+
+ $regex = '/
+ (?: zend_parse_parameters(?:_throw)? \s*\([^,]+
+ | zend_parse_(?:parameters_ex|method_parameters) \s*\([^,]+,[^,]+
+ | zend_parse_method_parameters_ex \s*\([^,]+,[^,]+,[^,+]
+ )
+ ,\s*"([^"]*)"\s*
+ ,\s*([^{;]*)
+ /Sx';
+ if (preg_match_all($regex, $txt, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
+
+ $GLOBALS['current_function'] = $name;
+
+ foreach ($matches as $m) {
+ $GLOBALS['error_few_vars_given'] = false;
+ update_lineno($offset + $m[2][1]);
+
+ $vars = get_vars(substr($txt, 0, $m[0][1])); // limit var search to current location
+ $params = get_params($vars, $m[2][0]);
+ $optional = $varargs = false;
+ $last_char = '';
+ $j = -1;
+
+ $spec = $m[1][0];
+ $len = strlen($spec);
+ for ($i = 0; $i < $len; ++$i) {
+ $char = $spec[$i];
+ switch ($char = $spec[$i]) {
+ // separator for optional parameters
+ case '|':
+ if ($optional) {
+ error("more than one optional separator at char #$i");
+ } else {
+ $optional = true;
+ if ($i == $len-1) {
+ error("unnecessary optional separator");
+ }
+ }
+ break;
+
+ // separate_zval_if_not_ref
+ case '/':
+ if (in_array($last_char, array('l', 'L', 'd', 'b'))) {
+ error("the '/' specifier should not be applied to '$last_char'");
+ }
+ break;
+
+ // nullable arguments
+ case '!':
+ if (in_array($last_char, array('l', 'L', 'd', 'b'))) {
+ check_param($params, ++$j, 'zend_bool*', $optional);
+ }
+ break;
+
+ // variadic arguments
+ case '+':
+ case '*':
+ if ($varargs) {
+ error("A varargs specifier can only be used once. repeated char at column $i");
+ } else {
+ check_param($params, ++$j, 'zval**', $optional);
+ check_param($params, ++$j, 'int*', $optional);
+ $varargs = true;
+ }
+ break;
+
+ case 's':
+ case 'p':
+ check_param($params, ++$j, 'char**', $optional, $allow_uninit=true);
+ check_param($params, ++$j, 'size_t*', $optional, $allow_uninit=true);
+ if ($optional && !$params[$j-1][2] && !$params[$j][2]
+ && $params[$j-1][0] !== '**dummy**' && $params[$j][0] !== '**dummy**') {
+ error("one of optional vars {$params[$j-1][0]} or {$params[$j][0]} must be initialized", 1);
+ }
+ break;
+
+ case 'C':
+ // C must always be initialized, independently of whether it's optional
+ check_param($params, ++$j, 'zend_class_entry**', false);
+ break;
+
+ default:
+ if (!isset($API_params[$char])) {
+ error("unknown char ('$char') at column $i");
+ }
+
+ // If an is_null flag is in use, only that flag is required to be
+ // initialized
+ $allow_uninit = $i+1 < $len && $spec[$i+1] === '!'
+ && in_array($char, array('l', 'L', 'd', 'b'));
+
+ foreach ($API_params[$char] as $exp) {
+ check_param($params, ++$j, $exp, $optional, $allow_uninit);
+ }
+ }
+
+ $last_char = $char;
+ }
+ }
+ }
}
/** the main recursion function. splits files in functions and calls the other functions */
function recurse($path)
{
- foreach (scandir($path) as $file) {
- if ($file == '.' || $file == '..' || $file == 'CVS') continue;
+ foreach (scandir($path) as $file) {
+ if ($file == '.' || $file == '..' || $file == 'CVS') continue;
- $file = "$path/$file";
- if (is_dir($file)) {
- recurse($file);
- continue;
- }
+ $file = "$path/$file";
+ if (is_dir($file)) {
+ recurse($file);
+ continue;
+ }
- // parse only .c and .cpp files
- if (substr_compare($file, '.c', -2) && substr_compare($file, '.cpp', -4)) continue;
+ // parse only .c and .cpp files
+ if (substr_compare($file, '.c', -2) && substr_compare($file, '.cpp', -4)) continue;
- $txt = file_get_contents($file);
- // remove comments (but preserve the number of lines)
- $txt = preg_replace('@//.*@S', '', $txt);
- $txt = preg_replace_callback('@/\*.*\*/@SsU', function($matches) {
- return preg_replace("/[^\r\n]+/S", "", $matches[0]);
- }, $txt);
+ $txt = file_get_contents($file);
+ // remove comments (but preserve the number of lines)
+ $txt = preg_replace('@//.*@S', '', $txt);
+ $txt = preg_replace_callback('@/\*.*\*/@SsU', function($matches) {
+ return preg_replace("/[^\r\n]+/S", "", $matches[0]);
+ }, $txt);
- $split = preg_split('/PHP_(?:NAMED_)?(?:FUNCTION|METHOD)\s*\((\w+(?:,\s*\w+)?)\)/S', $txt, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE);
+ $split = preg_split('/PHP_(?:NAMED_)?(?:FUNCTION|METHOD)\s*\((\w+(?:,\s*\w+)?)\)/S', $txt, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE);
- if (count($split) < 2) continue; // no functions defined on this file
- array_shift($split); // the first part isn't relevant
+ if (count($split) < 2) continue; // no functions defined on this file
+ array_shift($split); // the first part isn't relevant
- // generate the line offsets array
- $j = 0;
- $lines = preg_split("/(\r\n?|\n)/S", $txt, -1, PREG_SPLIT_DELIM_CAPTURE);
- $lines_offset = array();
+ // generate the line offsets array
+ $j = 0;
+ $lines = preg_split("/(\r\n?|\n)/S", $txt, -1, PREG_SPLIT_DELIM_CAPTURE);
+ $lines_offset = array();
- for ($i = 0; $i < count($lines); ++$i) {
- $j += strlen($lines[$i]) + strlen(@$lines[++$i]);
- $lines_offset[] = $j;
- }
+ for ($i = 0; $i < count($lines); ++$i) {
+ $j += strlen($lines[$i]) + strlen(@$lines[++$i]);
+ $lines_offset[] = $j;
+ }
- $GLOBALS['lines_offset'] = $lines_offset;
- $GLOBALS['current_file'] = $file;
+ $GLOBALS['lines_offset'] = $lines_offset;
+ $GLOBALS['current_file'] = $file;
- for ($i = 0; $i < count($split); $i+=2) {
- // if the /* }}} */ comment is found use it to reduce false positives
- // TODO: check the other indexes
- list($f) = preg_split('@/\*\s*}}}\s*\*/@S', $split[$i+1][0]);
- check_function(preg_replace('/\s*,\s*/S', '::', $split[$i][0]), $f, $split[$i][1]);
- }
- }
+ for ($i = 0; $i < count($split); $i+=2) {
+ // if the /* }}} */ comment is found use it to reduce false positives
+ // TODO: check the other indexes
+ list($f) = preg_split('@/\*\s*}}}\s*\*/@S', $split[$i+1][0]);
+ check_function(preg_replace('/\s*,\s*/S', '::', $split[$i][0]), $f, $split[$i][1]);
+ }
+ }
}
$dirs = array();
if (isset($argc) && $argc > 1) {
- if ($argv[1] == '-h' || $argv[1] == '-help' || $argv[1] == '--help') {
- echo <<<HELP
+ if ($argv[1] == '-h' || $argv[1] == '-help' || $argv[1] == '--help') {
+ echo <<<HELP
Synopsis:
php check_parameters.php [directories]
HELP;
- exit(0);
- }
- for ($i = 1; $i < $argc; $i++) {
- $dirs[] = $argv[$i];
- }
+ exit(0);
+ }
+ for ($i = 1; $i < $argc; $i++) {
+ $dirs[] = $argv[$i];
+ }
} else {
- $dirs[] = PHPDIR;
+ $dirs[] = PHPDIR;
}
foreach($dirs as $dir) {
- if (is_dir($dir)) {
- if (!is_readable($dir)) {
- echo "ERROR: directory '", $dir ,"' is not readable\n";
- exit(1);
- }
- } else {
- echo "ERROR: bogus directory '", $dir ,"'\n";
- exit(1);
- }
+ if (is_dir($dir)) {
+ if (!is_readable($dir)) {
+ echo "ERROR: directory '", $dir ,"' is not readable\n";
+ exit(1);
+ }
+ } else {
+ echo "ERROR: bogus directory '", $dir ,"'\n";
+ exit(1);
+ }
}
foreach ($dirs as $dir) {
- recurse(realpath($dir));
+ recurse(realpath($dir));
}
diff --git a/scripts/dev/find_tested.php b/scripts/dev/find_tested.php
index 9368ad3796..3b18879d2f 100755
--- a/scripts/dev/find_tested.php
+++ b/scripts/dev/find_tested.php
@@ -201,27 +201,27 @@ function get_phpt_files($dir, &$phpt_file_count, &$all_phpt)
* Extract tests from a specified file, returns an array of tested function tokens
*/
function extract_tests($file) {
- $code = file_get_contents($file);
+ $code = file_get_contents($file);
- if (!preg_match('/--FILE--\s*(.*)\s*--(EXPECTF|EXPECTREGEX|EXPECT)?--/is', $code, $r)) {
- //print "Unable to get code in ".$file."\n";
- return array();
- }
+ if (!preg_match('/--FILE--\s*(.*)\s*--(EXPECTF|EXPECTREGEX|EXPECT)?--/is', $code, $r)) {
+ //print "Unable to get code in ".$file."\n";
+ return array();
+ }
- $tokens = token_get_all($r[1]);
- $functions = array_filter($tokens, 'filter_functions');
- $functions = array_map( 'map_token_value',$functions);
- $functions = array_unique($functions);
+ $tokens = token_get_all($r[1]);
+ $functions = array_filter($tokens, 'filter_functions');
+ $functions = array_map( 'map_token_value',$functions);
+ $functions = array_unique($functions);
- return $functions;
+ return $functions;
}
function filter_functions($x) {
- return $x[0] == 307;
+ return $x[0] == 307;
}
function map_token_value($x) {
- return $x[1];
+ return $x[1];
}
diff --git a/scripts/dev/search_underscores.php b/scripts/dev/search_underscores.php
index fd2a54c183..bd74ea2af7 100755
--- a/scripts/dev/search_underscores.php
+++ b/scripts/dev/search_underscores.php
@@ -32,38 +32,38 @@ $classes = array_merge(get_declared_classes(), get_declared_interfaces());
$extensions = array();
foreach(get_loaded_extensions() as $ext) {
- $cnt_modules++;
- if (strpos($ext, "_") !== false) {
- $err++;
- $extensions[$ext] = array();
- }
+ $cnt_modules++;
+ if (strpos($ext, "_") !== false) {
+ $err++;
+ $extensions[$ext] = array();
+ }
}
$cnt_classes = count($classes);
foreach($classes as $c) {
- if (strpos($c, "_") !== false) {
- $err++;
- $ref = new ReflectionClass($c);
- if (!($ext = $ref->getExtensionName())) {;
- $ext = $ref->isInternal() ? "<internal>" : "<user>";
- }
- if (!array_key_exists($ext, $extensions)) {
- $extensions[$ext] = array();
- }
- $extensions[$ext][$c] = array();
- foreach(get_class_methods($c) as $method) {
- $cnt_methods++;
- if (strpos(substr($method, substr($method, 0, 2) != "__" ? 0 : 2), "_") !== false) {
- $err++;
- $extensions[$ext][$c][] = $method;
- }
- }
- }
- else
- {
- $cnt_methods += count(get_class_methods($c));
- }
+ if (strpos($c, "_") !== false) {
+ $err++;
+ $ref = new ReflectionClass($c);
+ if (!($ext = $ref->getExtensionName())) {;
+ $ext = $ref->isInternal() ? "<internal>" : "<user>";
+ }
+ if (!array_key_exists($ext, $extensions)) {
+ $extensions[$ext] = array();
+ }
+ $extensions[$ext][$c] = array();
+ foreach(get_class_methods($c) as $method) {
+ $cnt_methods++;
+ if (strpos(substr($method, substr($method, 0, 2) != "__" ? 0 : 2), "_") !== false) {
+ $err++;
+ $extensions[$ext][$c][] = $method;
+ }
+ }
+ }
+ else
+ {
+ $cnt_methods += count(get_class_methods($c));
+ }
}
$cnt = $cnt_modules + $cnt_classes + $cnt_methods;
@@ -79,15 +79,15 @@ printf("\n");
ksort($extensions);
foreach($extensions as $ext => &$classes) {
- echo "Extension: $ext\n";
- ksort($classes);
- foreach($classes as $classname => &$methods) {
- echo " Class: $classname\n";
- ksort($methods);
- foreach($methods as $method) {
- echo " Method: $method\n";
- }
- }
+ echo "Extension: $ext\n";
+ ksort($classes);
+ foreach($classes as $classname => &$methods) {
+ echo " Class: $classname\n";
+ ksort($methods);
+ foreach($methods as $method) {
+ echo " Method: $method\n";
+ }
+ }
}
printf("\n");
diff --git a/win32/build/mkdist.php b/win32/build/mkdist.php
index c119530c03..be8b7a5642 100644
--- a/win32/build/mkdist.php
+++ b/win32/build/mkdist.php
@@ -31,136 +31,136 @@ $pecl_dll_deps = array();
function get_depends($module)
{
- static $no_dist = array(
- /* windows system dlls that should not be bundled */
- 'advapi32.dll', 'comdlg32.dll', 'crypt32.dll', 'gdi32.dll', 'kernel32.dll', 'ntdll.dll',
- 'odbc32.dll', 'ole32.dll', 'oleaut32.dll', 'rpcrt4.dll',
- 'shell32.dll', 'shlwapi.dll', 'user32.dll', 'ws2_32.dll', 'ws2help.dll',
- 'comctl32.dll', 'winmm.dll', 'wsock32.dll', 'winspool.drv', 'msasn1.dll',
- 'secur32.dll', 'netapi32.dll', 'dnsapi.dll', 'psapi.dll', 'normaliz.dll',
- 'iphlpapi.dll', 'bcrypt.dll',
-
- /* apache */
- 'apachecore.dll',
-
- /* apache 2 */
- 'libhttpd.dll', 'libapr.dll', 'libaprutil.dll','libapr-1.dll', 'libaprutil-1.dll',
-
- /* oracle */
- 'oci.dll', 'ociw32.dll',
-
- /* sybase */
- 'libcs.dll', 'libct.dll',
-
- /* firebird */
- 'fbclient.dll',
-
- /* visual C++; mscvrt.dll is present on everyones system,
- * but the debug version (msvcrtd.dll) and those from visual studio.net
- * (msvcrt7x.dll) are not */
- 'msvcrt.dll',
- 'msvcr90.dll',
- 'wldap32.dll',
- 'vcruntime140.dll',
- 'msvcp140.dll',
- );
- static $no_dist_re = array(
- "api-ms-win-crt-.+\.dll",
- );
- global $build_dir, $extra_dll_deps, $ext_targets, $sapi_targets, $pecl_targets, $phpdll, $per_module_deps, $pecl_dll_deps;
-
- $bd = strtolower(realpath($build_dir));
-
- $is_pecl = in_array($module, $pecl_targets);
-
- $cmd = "$GLOBALS[build_dir]\\deplister.exe \"$module\" \"$GLOBALS[build_dir]\"";
- $proc = proc_open($cmd,
- array(1 => array("pipe", "w")),
- $pipes);
-
- $n = 0;
- while (($line = fgetcsv($pipes[1]))) {
- $n++;
-
- $dep = strtolower($line[0]);
- $depbase = basename($dep);
- /* ignore stuff in our build dir, but only if it is
- * one of our targets */
- if (((in_array($depbase, $sapi_targets) ||
- in_array($depbase, $ext_targets) || in_array($depbase, $pecl_targets)) ||
- $depbase == $phpdll) && file_exists($GLOBALS['build_dir'] . "/$depbase")) {
- continue;
- }
- /* ignore some well-known system dlls */
- if (in_array(basename($dep), $no_dist)) {
- continue;
- } else {
- $skip = false;
- foreach ($no_dist_re as $re) {
- if (preg_match(",$re,", basename($dep)) > 0) {
- $skip = true;
- break;
- }
- }
- if ($skip) {
- continue;
- }
- }
-
- if ($is_pecl) {
- if (!in_array($dep, $pecl_dll_deps)) {
- $pecl_dll_deps[] = $dep;
- }
- } else {
- if (!in_array($dep, $extra_dll_deps)) {
- $extra_dll_deps[] = $dep;
- }
- }
-
- if (!isset($per_module_deps[basename($module)]) || !in_array($dep, $per_module_deps[basename($module)])) {
- $per_module_deps[basename($module)][] = $dep;
- //recursively check dll dependencies
- get_depends($dep);
- }
- }
- fclose($pipes[1]);
- proc_close($proc);
+ static $no_dist = array(
+ /* windows system dlls that should not be bundled */
+ 'advapi32.dll', 'comdlg32.dll', 'crypt32.dll', 'gdi32.dll', 'kernel32.dll', 'ntdll.dll',
+ 'odbc32.dll', 'ole32.dll', 'oleaut32.dll', 'rpcrt4.dll',
+ 'shell32.dll', 'shlwapi.dll', 'user32.dll', 'ws2_32.dll', 'ws2help.dll',
+ 'comctl32.dll', 'winmm.dll', 'wsock32.dll', 'winspool.drv', 'msasn1.dll',
+ 'secur32.dll', 'netapi32.dll', 'dnsapi.dll', 'psapi.dll', 'normaliz.dll',
+ 'iphlpapi.dll', 'bcrypt.dll',
+
+ /* apache */
+ 'apachecore.dll',
+
+ /* apache 2 */
+ 'libhttpd.dll', 'libapr.dll', 'libaprutil.dll','libapr-1.dll', 'libaprutil-1.dll',
+
+ /* oracle */
+ 'oci.dll', 'ociw32.dll',
+
+ /* sybase */
+ 'libcs.dll', 'libct.dll',
+
+ /* firebird */
+ 'fbclient.dll',
+
+ /* visual C++; mscvrt.dll is present on everyones system,
+ * but the debug version (msvcrtd.dll) and those from visual studio.net
+ * (msvcrt7x.dll) are not */
+ 'msvcrt.dll',
+ 'msvcr90.dll',
+ 'wldap32.dll',
+ 'vcruntime140.dll',
+ 'msvcp140.dll',
+ );
+ static $no_dist_re = array(
+ "api-ms-win-crt-.+\.dll",
+ );
+ global $build_dir, $extra_dll_deps, $ext_targets, $sapi_targets, $pecl_targets, $phpdll, $per_module_deps, $pecl_dll_deps;
+
+ $bd = strtolower(realpath($build_dir));
+
+ $is_pecl = in_array($module, $pecl_targets);
+
+ $cmd = "$GLOBALS[build_dir]\\deplister.exe \"$module\" \"$GLOBALS[build_dir]\"";
+ $proc = proc_open($cmd,
+ array(1 => array("pipe", "w")),
+ $pipes);
+
+ $n = 0;
+ while (($line = fgetcsv($pipes[1]))) {
+ $n++;
+
+ $dep = strtolower($line[0]);
+ $depbase = basename($dep);
+ /* ignore stuff in our build dir, but only if it is
+ * one of our targets */
+ if (((in_array($depbase, $sapi_targets) ||
+ in_array($depbase, $ext_targets) || in_array($depbase, $pecl_targets)) ||
+ $depbase == $phpdll) && file_exists($GLOBALS['build_dir'] . "/$depbase")) {
+ continue;
+ }
+ /* ignore some well-known system dlls */
+ if (in_array(basename($dep), $no_dist)) {
+ continue;
+ } else {
+ $skip = false;
+ foreach ($no_dist_re as $re) {
+ if (preg_match(",$re,", basename($dep)) > 0) {
+ $skip = true;
+ break;
+ }
+ }
+ if ($skip) {
+ continue;
+ }
+ }
+
+ if ($is_pecl) {
+ if (!in_array($dep, $pecl_dll_deps)) {
+ $pecl_dll_deps[] = $dep;
+ }
+ } else {
+ if (!in_array($dep, $extra_dll_deps)) {
+ $extra_dll_deps[] = $dep;
+ }
+ }
+
+ if (!isset($per_module_deps[basename($module)]) || !in_array($dep, $per_module_deps[basename($module)])) {
+ $per_module_deps[basename($module)][] = $dep;
+ //recursively check dll dependencies
+ get_depends($dep);
+ }
+ }
+ fclose($pipes[1]);
+ proc_close($proc);
//echo "Module $module [$n lines]\n";
}
function copy_file_list($source_dir, $dest_dir, $list)
{
- global $is_debug, $dist_dir;
-
- foreach ($list as $item) {
- if (empty($item)) {
- continue;
- } elseif (!is_file($source_dir . DIRECTORY_SEPARATOR . $item)) {
- echo "WARNING: $item not found\n";
- continue;
- }
-
- echo "Copying $item from $source_dir to $dest_dir\n";
- copy($source_dir . DIRECTORY_SEPARATOR . $item, $dest_dir . DIRECTORY_SEPARATOR . $item);
- if ($is_debug) {
- $itemdb = preg_replace("/\.(exe|dll|lib)$/i", ".pdb", $item);
- if (file_exists("$source_dir/$itemdb")) {
- copy("$source_dir/$itemdb", "$dist_dir/dev/$itemdb");
- }
- }
- if (preg_match("/\.(exe|dll)$/i", $item)) {
- get_depends($source_dir . '/' . $item);
- }
- }
+ global $is_debug, $dist_dir;
+
+ foreach ($list as $item) {
+ if (empty($item)) {
+ continue;
+ } elseif (!is_file($source_dir . DIRECTORY_SEPARATOR . $item)) {
+ echo "WARNING: $item not found\n";
+ continue;
+ }
+
+ echo "Copying $item from $source_dir to $dest_dir\n";
+ copy($source_dir . DIRECTORY_SEPARATOR . $item, $dest_dir . DIRECTORY_SEPARATOR . $item);
+ if ($is_debug) {
+ $itemdb = preg_replace("/\.(exe|dll|lib)$/i", ".pdb", $item);
+ if (file_exists("$source_dir/$itemdb")) {
+ copy("$source_dir/$itemdb", "$dist_dir/dev/$itemdb");
+ }
+ }
+ if (preg_match("/\.(exe|dll)$/i", $item)) {
+ get_depends($source_dir . '/' . $item);
+ }
+ }
}
function copy_text_file($source, $dest)
{
- $text = file_get_contents($source);
- $text = preg_replace("/(\r\n?)|\n/", "\r\n", $text);
- $fp = fopen($dest, "w");
- fwrite($fp, $text);
- fclose($fp);
+ $text = file_get_contents($source);
+ $text = preg_replace("/(\r\n?)|\n/", "\r\n", $text);
+ $fp = fopen($dest, "w");
+ fwrite($fp, $text);
+ fclose($fp);
}
/* very light-weight function to extract a single named file from
@@ -168,57 +168,57 @@ function copy_text_file($source, $dest)
* based on the PEAR info set in $packages. */
function extract_file_from_tarball($pkg, $filename, $dest_dir) /* {{{ */
{
- global $packages;
-
- $name = $pkg . '-' . $packages[$pkg];
- $tarball = $dest_dir . "/" . $name . '.tgz';
- $filename = $name . '/' . $filename;
- $destfilename = $dest_dir . "/" . basename($filename);
-
- $fp = gzopen($tarball, 'rb');
-
- $done = false;
- do {
- /* read the header */
- $hdr_data = gzread($fp, 512);
- if (strlen($hdr_data) == 0)
- break;
- $checksum = 0;
- for ($i = 0; $i < 148; $i++)
- $checksum += ord($hdr_data{$i});
- for ($i = 148; $i < 156; $i++)
- $checksum += 32;
- for ($i = 156; $i < 512; $i++)
- $checksum += ord($hdr_data{$i});
-
- $hdr = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $hdr_data);
-
- $hdr['checksum'] = octdec(trim($hdr['checksum']));
-
- if ($hdr['checksum'] != $checksum) {
- echo "Checksum for $tarball $hdr[filename] is invalid\n";
- print_r($hdr);
- return;
- }
-
- $hdr['size'] = octdec(trim($hdr['size']));
- echo "File: $hdr[filename] $hdr[size]\n";
-
- if ($filename == $hdr['filename']) {
- echo "Found the file we want\n";
- $dest = fopen($destfilename, 'wb');
- $x = stream_copy_to_stream($fp, $dest, $hdr['size']);
- fclose($dest);
- echo "Wrote $x bytes into $destfilename\n";
- break;
- }
-
- /* skip body of the file */
- $size = 512 * ceil((int)$hdr['size'] / 512);
- echo "Skipping $size bytes\n";
- gzseek($fp, gztell($fp) + $size);
-
- } while (!$done);
+ global $packages;
+
+ $name = $pkg . '-' . $packages[$pkg];
+ $tarball = $dest_dir . "/" . $name . '.tgz';
+ $filename = $name . '/' . $filename;
+ $destfilename = $dest_dir . "/" . basename($filename);
+
+ $fp = gzopen($tarball, 'rb');
+
+ $done = false;
+ do {
+ /* read the header */
+ $hdr_data = gzread($fp, 512);
+ if (strlen($hdr_data) == 0)
+ break;
+ $checksum = 0;
+ for ($i = 0; $i < 148; $i++)
+ $checksum += ord($hdr_data{$i});
+ for ($i = 148; $i < 156; $i++)
+ $checksum += 32;
+ for ($i = 156; $i < 512; $i++)
+ $checksum += ord($hdr_data{$i});
+
+ $hdr = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $hdr_data);
+
+ $hdr['checksum'] = octdec(trim($hdr['checksum']));
+
+ if ($hdr['checksum'] != $checksum) {
+ echo "Checksum for $tarball $hdr[filename] is invalid\n";
+ print_r($hdr);
+ return;
+ }
+
+ $hdr['size'] = octdec(trim($hdr['size']));
+ echo "File: $hdr[filename] $hdr[size]\n";
+
+ if ($filename == $hdr['filename']) {
+ echo "Found the file we want\n";
+ $dest = fopen($destfilename, 'wb');
+ $x = stream_copy_to_stream($fp, $dest, $hdr['size']);
+ fclose($dest);
+ echo "Wrote $x bytes into $destfilename\n";
+ break;
+ }
+
+ /* skip body of the file */
+ $size = 512 * ceil((int)$hdr['size'] / 512);
+ echo "Skipping $size bytes\n";
+ gzseek($fp, gztell($fp) + $size);
+
+ } while (!$done);
} /* }}} */
@@ -233,8 +233,8 @@ $phplib = str_replace(".dll", ".lib", $phpdll);
copy("$build_dir/$phplib", "$dist_dir/dev/$phplib");
/* debug builds; copy the symbols too */
if ($is_debug) {
- $phppdb = str_replace(".dll", ".pdb", $phpdll);
- copy("$build_dir/$phppdb", "$dist_dir/dev/$phppdb");
+ $phppdb = str_replace(".dll", ".pdb", $phpdll);
+ copy("$build_dir/$phppdb", "$dist_dir/dev/$phppdb");
}
/* copy the sapi */
copy_file_list($build_dir, "$dist_dir", $sapi_targets);
@@ -244,30 +244,30 @@ copy_file_list($build_dir, "$dist_dir/ext", $ext_targets);
/* pecl sapi and extensions */
if(sizeof($pecl_targets)) {
- copy_file_list($build_dir, $pecl_dir, $pecl_targets);
+ copy_file_list($build_dir, $pecl_dir, $pecl_targets);
}
/* populate reading material */
$text_files = array(
- "LICENSE" => "license.txt",
- "NEWS" => "news.txt",
- "README.md" => "README.md",
- "README.REDIST.BINS" => "readme-redist-bins.txt",
- "php.ini-development" => "php.ini-development",
- "php.ini-production" => "php.ini-production"
+ "LICENSE" => "license.txt",
+ "NEWS" => "news.txt",
+ "README.md" => "README.md",
+ "README.REDIST.BINS" => "readme-redist-bins.txt",
+ "php.ini-development" => "php.ini-development",
+ "php.ini-production" => "php.ini-production"
);
foreach ($text_files as $src => $dest) {
- copy_text_file($src, $dist_dir . '/' . $dest);
+ copy_text_file($src, $dist_dir . '/' . $dest);
}
/* general other files */
$general_files = array(
- "$GLOBALS[build_dir]\\deplister.exe" => "deplister.exe",
+ "$GLOBALS[build_dir]\\deplister.exe" => "deplister.exe",
);
foreach ($general_files as $src => $dest) {
- copy($src, $dist_dir . '/' . $dest);
+ copy($src, $dist_dir . '/' . $dest);
}
/* include a snapshot identifier */
@@ -289,40 +289,40 @@ $exts = get_loaded_extensions();
fprintf($fp, "\r\nBuilt-in Extensions\r\n");
fwrite($fp, "===========================\r\n");
foreach ($exts as $ext) {
- fprintf($fp, "%s\r\n", $ext);
+ fprintf($fp, "%s\r\n", $ext);
}
fwrite($fp, "\r\n\r\n");
/* list dependencies */
fprintf($fp, "Dependency information:\r\n");
foreach ($per_module_deps as $modulename => $deps) {
- if (in_array($modulename, $pecl_targets))
- continue;
-
- fprintf($fp, "Module: %s\r\n", $modulename);
- fwrite($fp, "===========================\r\n");
- foreach ($deps as $dll) {
- fprintf($fp, "\t%s\r\n", basename($dll));
- }
- fwrite($fp, "\r\n");
+ if (in_array($modulename, $pecl_targets))
+ continue;
+
+ fprintf($fp, "Module: %s\r\n", $modulename);
+ fwrite($fp, "===========================\r\n");
+ foreach ($deps as $dll) {
+ fprintf($fp, "\t%s\r\n", basename($dll));
+ }
+ fwrite($fp, "\r\n");
}
fclose($fp);
/* Now add those dependencies */
foreach ($extra_dll_deps as $dll) {
- if (!file_exists($dll)) {
- /* try template dir */
- $tdll = $snapshot_template . "/dlls/" . basename($dll);
- if (!file_exists($tdll)) {
- $tdll = $php_build_dir . '/bin/' . basename($dll);
- if (!file_exists($tdll)) {
- echo "WARNING: distro depends on $dll, but could not find it on your system\n";
- continue;
- }
- }
- $dll = $tdll;
- }
- copy($dll, "$dist_dir/" . basename($dll));
+ if (!file_exists($dll)) {
+ /* try template dir */
+ $tdll = $snapshot_template . "/dlls/" . basename($dll);
+ if (!file_exists($tdll)) {
+ $tdll = $php_build_dir . '/bin/' . basename($dll);
+ if (!file_exists($tdll)) {
+ echo "WARNING: distro depends on $dll, but could not find it on your system\n";
+ continue;
+ }
+ }
+ $dll = $tdll;
+ }
+ copy($dll, "$dist_dir/" . basename($dll));
}
/* TODO:
@@ -333,168 +333,168 @@ deps. For example, libenchant.dll loads libenchant_myspell.dll or
libenchant_ispell.dll
*/
$ENCHANT_DLLS = array(
- array('', 'glib-2.dll'),
- array('', 'gmodule-2.dll'),
- array('lib/enchant', 'libenchant_myspell.dll'),
- array('lib/enchant', 'libenchant_ispell.dll'),
+ array('', 'glib-2.dll'),
+ array('', 'gmodule-2.dll'),
+ array('lib/enchant', 'libenchant_myspell.dll'),
+ array('lib/enchant', 'libenchant_ispell.dll'),
);
foreach ($ENCHANT_DLLS as $dll) {
- $dest = "$dist_dir/$dll[0]";
- $filename = $dll[1];
-
- if (!file_exists("$dest") || !is_dir("$dest")) {
- if (!mkdir("$dest", 0777, true)) {
- echo "WARNING: couldn't create '$dest' for enchant plugins ";
- }
- }
-
- if (!copy($php_build_dir . '/bin/' . $filename, "$dest/" . basename($filename))) {
- echo "WARNING: couldn't copy $filename into the dist dir";
- }
+ $dest = "$dist_dir/$dll[0]";
+ $filename = $dll[1];
+
+ if (!file_exists("$dest") || !is_dir("$dest")) {
+ if (!mkdir("$dest", 0777, true)) {
+ echo "WARNING: couldn't create '$dest' for enchant plugins ";
+ }
+ }
+
+ if (!copy($php_build_dir . '/bin/' . $filename, "$dest/" . basename($filename))) {
+ echo "WARNING: couldn't copy $filename into the dist dir";
+ }
}
$SASL_DLLS = $php_build_dir . "/bin/sasl2/sasl*.dll";
$fls = glob($SASL_DLLS);
if (!empty($fls)) {
- $sasl_dest_dir = "$dist_dir/sasl2";
- if (!file_exists($sasl_dest_dir) || !is_dir($sasl_dest_dir)) {
- if (!mkdir("$sasl_dest_dir", 0777, true)) {
- echo "WARNING: couldn't create '$sasl_dest_dir' for SASL2 auth plugins ";
- }
- }
- foreach ($fls as $fl) {
- if (!copy($fl, "$sasl_dest_dir/" . basename($fl))) {
- echo "WARNING: couldn't copy $fl into the $sasl_dest_dir";
- }
- }
+ $sasl_dest_dir = "$dist_dir/sasl2";
+ if (!file_exists($sasl_dest_dir) || !is_dir($sasl_dest_dir)) {
+ if (!mkdir("$sasl_dest_dir", 0777, true)) {
+ echo "WARNING: couldn't create '$sasl_dest_dir' for SASL2 auth plugins ";
+ }
+ }
+ foreach ($fls as $fl) {
+ if (!copy($fl, "$sasl_dest_dir/" . basename($fl))) {
+ echo "WARNING: couldn't copy $fl into the $sasl_dest_dir";
+ }
+ }
}
/* and those for pecl */
foreach ($pecl_dll_deps as $dll) {
- if (in_array($dll, $extra_dll_deps)) {
- /* already in main distro */
- continue;
- }
- if (!file_exists($dll)) {
- /* try template dir */
- $tdll = $snapshot_template . "/dlls/" . basename($dll);
- if (!file_exists($tdll)) {
- echo "WARNING: distro depends on $dll, but could not find it on your system\n";
- continue;
- }
- $dll = $tdll;
- }
- copy($dll, "$pecl_dir/" . basename($dll));
+ if (in_array($dll, $extra_dll_deps)) {
+ /* already in main distro */
+ continue;
+ }
+ if (!file_exists($dll)) {
+ /* try template dir */
+ $tdll = $snapshot_template . "/dlls/" . basename($dll);
+ if (!file_exists($tdll)) {
+ echo "WARNING: distro depends on $dll, but could not find it on your system\n";
+ continue;
+ }
+ $dll = $tdll;
+ }
+ copy($dll, "$pecl_dir/" . basename($dll));
}
function copy_dir($source, $dest)
{
- if (!is_dir($dest)) {
- if (!mkdir($dest)) {
- return false;
- }
- }
-
- $d = opendir($source);
- while (($f = readdir($d)) !== false) {
- if ($f == '.' || $f == '..' || $f == '.svn') {
- continue;
- }
- $fs = $source . '/' . $f;
- $fd = $dest . '/' . $f;
- if (is_dir($fs)) {
- copy_dir($fs, $fd);
- } else {
- copy($fs, $fd);
- }
- }
- closedir($d);
+ if (!is_dir($dest)) {
+ if (!mkdir($dest)) {
+ return false;
+ }
+ }
+
+ $d = opendir($source);
+ while (($f = readdir($d)) !== false) {
+ if ($f == '.' || $f == '..' || $f == '.svn') {
+ continue;
+ }
+ $fs = $source . '/' . $f;
+ $fd = $dest . '/' . $f;
+ if (is_dir($fs)) {
+ copy_dir($fs, $fd);
+ } else {
+ copy($fs, $fd);
+ }
+ }
+ closedir($d);
}
function copy_test_dir($directory, $dest)
{
- if(substr($directory,-1) == '/') {
- $directory = substr($directory,0,-1);
- }
-
- if ($directory == 'tests' || $directory == 'examples') {
- if (!is_dir($dest . '/tests')) {
- mkdir($dest . '/tests', 0775, true);
- }
- copy_dir($directory, $dest . '/tests/');
-
- return false;
- }
-
- if(!file_exists($directory) || !is_dir($directory)) {
- echo "failed... $directory\n";
- return FALSE;
- }
-
- $directory_list = opendir($directory);
-
- while (FALSE !== ($file = readdir($directory_list))) {
- $full_path = $directory . '/' . $file;
- if($file != '.' && $file != '..' && $file != '.svn' && is_dir($full_path)) {
- if ($file == 'tests' || $file == 'examples') {
- if (!is_dir($dest . '/' . $full_path)) {
- mkdir($dest . '/' . $full_path , 0775, true);
- }
- copy_dir($full_path, $dest . '/' . $full_path . '/');
- continue;
- } else {
- copy_test_dir($full_path, $dest);
- }
- }
- }
-
- closedir($directory_list);
+ if(substr($directory,-1) == '/') {
+ $directory = substr($directory,0,-1);
+ }
+
+ if ($directory == 'tests' || $directory == 'examples') {
+ if (!is_dir($dest . '/tests')) {
+ mkdir($dest . '/tests', 0775, true);
+ }
+ copy_dir($directory, $dest . '/tests/');
+
+ return false;
+ }
+
+ if(!file_exists($directory) || !is_dir($directory)) {
+ echo "failed... $directory\n";
+ return FALSE;
+ }
+
+ $directory_list = opendir($directory);
+
+ while (FALSE !== ($file = readdir($directory_list))) {
+ $full_path = $directory . '/' . $file;
+ if($file != '.' && $file != '..' && $file != '.svn' && is_dir($full_path)) {
+ if ($file == 'tests' || $file == 'examples') {
+ if (!is_dir($dest . '/' . $full_path)) {
+ mkdir($dest . '/' . $full_path , 0775, true);
+ }
+ copy_dir($full_path, $dest . '/' . $full_path . '/');
+ continue;
+ } else {
+ copy_test_dir($full_path, $dest);
+ }
+ }
+ }
+
+ closedir($directory_list);
}
function make_phar_dot_phar($dist_dir)
{
- if (!extension_loaded('phar')) {
- return;
- }
+ if (!extension_loaded('phar')) {
+ return;
+ }
- $path_to_phar = realpath(__DIR__ . '/../../ext/phar');
+ $path_to_phar = realpath(__DIR__ . '/../../ext/phar');
- echo "Generating pharcommand.phar\n";
- $phar = new Phar($dist_dir . '/pharcommand.phar', 0, 'pharcommand');
+ echo "Generating pharcommand.phar\n";
+ $phar = new Phar($dist_dir . '/pharcommand.phar', 0, 'pharcommand');
- foreach (new DirectoryIterator($path_to_phar . '/phar') as $file) {
- if ($file->isDir() || $file == 'phar.php') {
- continue;
- }
+ foreach (new DirectoryIterator($path_to_phar . '/phar') as $file) {
+ if ($file->isDir() || $file == 'phar.php') {
+ continue;
+ }
- echo 'adding ', $file, "\n";
- $phar[(string) $file] = file_get_contents($path_to_phar. '/phar/' . $file);
- }
+ echo 'adding ', $file, "\n";
+ $phar[(string) $file] = file_get_contents($path_to_phar. '/phar/' . $file);
+ }
- $phar->setSignatureAlgorithm(Phar::SHA1);
- $stub = file($path_to_phar . '/phar/phar.php');
+ $phar->setSignatureAlgorithm(Phar::SHA1);
+ $stub = file($path_to_phar . '/phar/phar.php');
- unset($stub[0]); // remove hashbang
- $phar->setStub(implode('', $stub));
+ unset($stub[0]); // remove hashbang
+ $phar->setStub(implode('', $stub));
- echo "Creating phar.phar.bat\n";
- file_put_contents($dist_dir . '/phar.phar.bat', "\"%~dp0php.exe\" \"%~dp0pharcommand.phar\" %*\r\n");
+ echo "Creating phar.phar.bat\n";
+ file_put_contents($dist_dir . '/phar.phar.bat', "\"%~dp0php.exe\" \"%~dp0pharcommand.phar\" %*\r\n");
}
if (!is_dir($test_dir)) {
- mkdir($test_dir);
+ mkdir($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-tests.php');
@@ -503,82 +503,82 @@ copy('run-tests.php', $test_dir . '/run-tests.php');
$use_pear_template = true;
if (!$use_pear_template) {
- /* Let's do a PEAR-less pear setup */
- mkdir("$dist_dir/PEAR");
- mkdir("$dist_dir/PEAR/go-pear-bundle");
-
- /* grab the bootstrap script */
- echo "Downloading go-pear\n";
- copy("https://pear.php.net/go-pear.phar", "$dist_dir/PEAR/go-pear.php");
-
- /* import the package list -- sets $packages variable */
- include "pear/go-pear-list.php";
-
- /* download the packages into the destination */
- echo "Fetching packages\n";
-
- foreach ($packages as $name => $version) {
- $filename = "$name-$version.tgz";
- $destfilename = "$dist_dir/PEAR/go-pear-bundle/$filename";
- if (file_exists($destfilename))
- continue;
- $url = "http://pear.php.net/get/$filename";
- echo "Downloading $name from $url\n";
- flush();
- copy($url, $destfilename);
- }
-
- echo "Download complete. Extracting bootstrap files\n";
-
- /* Now, we want PEAR.php, Getopt.php (Console_Getopt) and Tar.php (Archive_Tar)
- * broken out of the tarballs */
- extract_file_from_tarball('PEAR', 'PEAR.php', "$dist_dir/PEAR/go-pear-bundle");
- extract_file_from_tarball('Archive_Tar', 'Archive/Tar.php', "$dist_dir/PEAR/go-pear-bundle");
- extract_file_from_tarball('Console_Getopt', 'Console/Getopt.php', "$dist_dir/PEAR/go-pear-bundle");
+ /* Let's do a PEAR-less pear setup */
+ mkdir("$dist_dir/PEAR");
+ mkdir("$dist_dir/PEAR/go-pear-bundle");
+
+ /* grab the bootstrap script */
+ echo "Downloading go-pear\n";
+ copy("https://pear.php.net/go-pear.phar", "$dist_dir/PEAR/go-pear.php");
+
+ /* import the package list -- sets $packages variable */
+ include "pear/go-pear-list.php";
+
+ /* download the packages into the destination */
+ echo "Fetching packages\n";
+
+ foreach ($packages as $name => $version) {
+ $filename = "$name-$version.tgz";
+ $destfilename = "$dist_dir/PEAR/go-pear-bundle/$filename";
+ if (file_exists($destfilename))
+ continue;
+ $url = "http://pear.php.net/get/$filename";
+ echo "Downloading $name from $url\n";
+ flush();
+ copy($url, $destfilename);
+ }
+
+ echo "Download complete. Extracting bootstrap files\n";
+
+ /* Now, we want PEAR.php, Getopt.php (Console_Getopt) and Tar.php (Archive_Tar)
+ * broken out of the tarballs */
+ extract_file_from_tarball('PEAR', 'PEAR.php', "$dist_dir/PEAR/go-pear-bundle");
+ extract_file_from_tarball('Archive_Tar', 'Archive/Tar.php', "$dist_dir/PEAR/go-pear-bundle");
+ extract_file_from_tarball('Console_Getopt', 'Console/Getopt.php', "$dist_dir/PEAR/go-pear-bundle");
}
/* add extras from the template dir */
if (file_exists($snapshot_template)) {
- $items = glob("$snapshot_template/*");
- print_r($items);
-
- foreach ($items as $item) {
- $bi = basename($item);
- if (is_dir($item)) {
- if ($bi == 'dlls' || $bi == 'symbols') {
- continue;
- } else if ($bi == 'PEAR') {
- if ($use_pear_template) {
- /* copy to top level */
- copy_dir($item, "$dist_dir/$bi");
- }
- } else {
- /* copy that dir into extras */
- copy_dir($item, "$dist_dir/extras/$bi");
- }
- } else {
- if ($bi == 'go-pear.bat') {
- /* copy to top level */
- copy($item, "$dist_dir/$bi");
- } else {
- /* copy to extras */
- copy($item, "$dist_dir/extras/$bi");
- }
- }
- }
-
- /* copy c++ runtime */
- $items = glob("$snapshot_template/dlls/*.CRT");
-
- foreach ($items as $item) {
- $bi = basename($item);
- if (is_dir($item)) {
- copy_dir($item, "$dist_dir/$bi");
- copy_dir($item, "$dist_dir/ext/$bi");
- }
- }
+ $items = glob("$snapshot_template/*");
+ print_r($items);
+
+ foreach ($items as $item) {
+ $bi = basename($item);
+ if (is_dir($item)) {
+ if ($bi == 'dlls' || $bi == 'symbols') {
+ continue;
+ } else if ($bi == 'PEAR') {
+ if ($use_pear_template) {
+ /* copy to top level */
+ copy_dir($item, "$dist_dir/$bi");
+ }
+ } else {
+ /* copy that dir into extras */
+ copy_dir($item, "$dist_dir/extras/$bi");
+ }
+ } else {
+ if ($bi == 'go-pear.bat') {
+ /* copy to top level */
+ copy($item, "$dist_dir/$bi");
+ } else {
+ /* copy to extras */
+ copy($item, "$dist_dir/extras/$bi");
+ }
+ }
+ }
+
+ /* copy c++ runtime */
+ $items = glob("$snapshot_template/dlls/*.CRT");
+
+ foreach ($items as $item) {
+ $bi = basename($item);
+ if (is_dir($item)) {
+ copy_dir($item, "$dist_dir/$bi");
+ copy_dir($item, "$dist_dir/ext/$bi");
+ }
+ }
} else {
- echo "WARNING: you don't have a snapshot template, your dist will not be complete\n";
+ echo "WARNING: you don't have a snapshot template, your dist will not be complete\n";
}
make_phar_dot_phar($dist_dir);
diff --git a/win32/ioutil.c b/win32/ioutil.c
index bb3ff39605..8cd704c662 100644
--- a/win32/ioutil.c
+++ b/win32/ioutil.c
@@ -1161,8 +1161,8 @@ PW32IO ssize_t php_win32_ioutil_readlink_w(const wchar_t *path, wchar_t *buf, si
ret = php_win32_ioutil_readlink_int(h, buf, buf_len);
- if (ret < 0) {
- wchar_t target[PHP_WIN32_IOUTIL_MAXPATHLEN];
+ if (ret < 0) {
+ wchar_t target[PHP_WIN32_IOUTIL_MAXPATHLEN];
size_t target_len;
size_t offset = 0;
diff --git a/win32/winutil.c b/win32/winutil.c
index a431025db8..7da505b1b4 100644
--- a/win32/winutil.c
+++ b/win32/winutil.c
@@ -447,7 +447,7 @@ static zend_always_inline BOOL is_compatible(const char *name, BOOL is_smaller,
free(err_txt);
return FALSE;
}
-
+
DWORD major = img->FileHeader->OptionalHeader.MajorLinkerVersion;
DWORD minor = img->FileHeader->OptionalHeader.MinorLinkerVersion;
@@ -459,7 +459,7 @@ static zend_always_inline BOOL is_compatible(const char *name, BOOL is_smaller,
is used with a newer CRT, but not the other way round.
Otherwise, if the linker major version is not same, it is an error, as
per the current knowledge.
-
+
This check is to be extended as new VS versions come out. */
DWORD core_minor = (DWORD)(PHP_LINKER_MINOR/10);
DWORD comp_minor = (DWORD)(minor/10);