diff options
Diffstat (limited to 'Zend')
92 files changed, 23094 insertions, 22680 deletions
diff --git a/Zend/bench.php b/Zend/bench.php index 5f771803cc..818ce5fbaf 100644 --- a/Zend/bench.php +++ b/Zend/bench.php @@ -418,5 +418,5 @@ sieve(30); $t = end_test($t, "sieve(30)"); strcat(200000); $t = end_test($t, "strcat(200000)"); -total($t0, "Total"); +total(); ?> diff --git a/Zend/tests/class_constants_005.phpt b/Zend/tests/class_constants_005.phpt new file mode 100644 index 0000000000..de53c2c0ca --- /dev/null +++ b/Zend/tests/class_constants_005.phpt @@ -0,0 +1,12 @@ +--TEST-- +String interning during constants substitution +--INI-- +opcache.enable_cli=0 +--FILE-- +<?php +define ("A", "." . ord(26) . "."); +eval("class A {const a = A;}"); +var_dump(A::a); +?> +--EXPECT-- +string(4) ".50." diff --git a/Zend/tests/function_arguments/call_with_leading_comma_error.phpt b/Zend/tests/function_arguments/call_with_leading_comma_error.phpt new file mode 100644 index 0000000000..1f587dd8f5 --- /dev/null +++ b/Zend/tests/function_arguments/call_with_leading_comma_error.phpt @@ -0,0 +1,8 @@ +--TEST-- +Leading commas in function calls is not allowed +--FILE-- +<?php +foo(,$foo); +?> +--EXPECTF-- +Parse error: syntax error, unexpected ',' in %s on line %d diff --git a/Zend/tests/function_arguments/call_with_multi_inner_comma_error.phpt b/Zend/tests/function_arguments/call_with_multi_inner_comma_error.phpt new file mode 100644 index 0000000000..d8250536da --- /dev/null +++ b/Zend/tests/function_arguments/call_with_multi_inner_comma_error.phpt @@ -0,0 +1,8 @@ +--TEST-- +Multiple inner commas in function calls is not allowed +--FILE-- +<?php +foo($foo,,$bar); +?> +--EXPECTF-- +Parse error: syntax error, unexpected ',', expecting ')' in %s on line %d diff --git a/Zend/tests/function_arguments/call_with_multi_trailing_comma_error.phpt b/Zend/tests/function_arguments/call_with_multi_trailing_comma_error.phpt new file mode 100644 index 0000000000..a38a01644b --- /dev/null +++ b/Zend/tests/function_arguments/call_with_multi_trailing_comma_error.phpt @@ -0,0 +1,8 @@ +--TEST-- +Multiple trailing commas in function calls is not allowed +--FILE-- +<?php +foo($foo,,); +?> +--EXPECTF-- +Parse error: syntax error, unexpected ',', expecting ')' in %s on line %d diff --git a/Zend/tests/function_arguments/call_with_only_comma_error.phpt b/Zend/tests/function_arguments/call_with_only_comma_error.phpt new file mode 100644 index 0000000000..8a0ce6810d --- /dev/null +++ b/Zend/tests/function_arguments/call_with_only_comma_error.phpt @@ -0,0 +1,8 @@ +--TEST-- +Single comma in function calls is not allowed +--FILE-- +<?php +foo(,); +?> +--EXPECTF-- +Parse error: syntax error, unexpected ',' in %s on line %d diff --git a/Zend/tests/function_arguments/call_with_trailing_comma_basic.phpt b/Zend/tests/function_arguments/call_with_trailing_comma_basic.phpt new file mode 100644 index 0000000000..f6a7603790 --- /dev/null +++ b/Zend/tests/function_arguments/call_with_trailing_comma_basic.phpt @@ -0,0 +1,97 @@ +--TEST-- +Allow trailing commas in function and method calls +--FILE-- +<?php +function foo(...$args) { + echo __FUNCTION__ . "\n"; + var_dump($args); +} +foo( + 'function', + 'bar', +); + +class Foo +{ + public function __construct(...$args) { + echo __FUNCTION__ . "\n"; + var_dump($args); + } + + public function bar(...$args) { + echo __FUNCTION__ . "\n"; + var_dump($args); + } + + public function __invoke(...$args) { + echo __FUNCTION__ . "\n"; + var_dump($args); + } +} + +$foo = new Foo( + 'constructor', + 'bar', +); + +$foo->bar( + 'method', + 'bar', +); + +$foo( + 'invoke', + 'bar', +); + +$bar = function(...$args) { + echo __FUNCTION__ . "\n"; + var_dump($args); +}; + +$bar( + 'closure', + 'bar', +); + +# Make sure to hit the "not really a function" language constructs +unset($foo, $bar,); +var_dump(isset($foo, $bar,)); +?> +--EXPECT-- +foo +array(2) { + [0]=> + string(8) "function" + [1]=> + string(3) "bar" +} +__construct +array(2) { + [0]=> + string(11) "constructor" + [1]=> + string(3) "bar" +} +bar +array(2) { + [0]=> + string(6) "method" + [1]=> + string(3) "bar" +} +__invoke +array(2) { + [0]=> + string(6) "invoke" + [1]=> + string(3) "bar" +} +{closure} +array(2) { + [0]=> + string(7) "closure" + [1]=> + string(3) "bar" +} +bool(false) diff --git a/Zend/tests/gc_029.phpt b/Zend/tests/gc_029.phpt index 3873d8becd..215d0e0e3b 100644 --- a/Zend/tests/gc_029.phpt +++ b/Zend/tests/gc_029.phpt @@ -1,7 +1,5 @@ --TEST-- GC 029: GC and destructors ---SKIPIF-- -<?php if (PHP_ZTS) { print "skip only for no-zts build"; } --INI-- zend.enable_gc=1 --FILE-- diff --git a/Zend/tests/gc_029_zts.phpt b/Zend/tests/gc_029_zts.phpt deleted file mode 100644 index 5d16e83348..0000000000 --- a/Zend/tests/gc_029_zts.phpt +++ /dev/null @@ -1,37 +0,0 @@ ---TEST-- -GC 029: GC and destructors ---SKIPIF-- -<?php if (!PHP_ZTS) { print "skip only for zts build"; } ---INI-- -zend.enable_gc=1 ---FILE-- -<?php -class Foo { - public $bar; - public $x = array(1,2,3); - function __destruct() { - if ($this->bar !== null) { - $this->x = null; - unset($this->bar); - } - } -} -class Bar { - public $foo; - function __destruct() { - if ($this->foo !== null) { - unset($this->foo); - } - } - -} -$foo = new Foo(); -$bar = new Bar(); -$foo->bar = $bar; -$bar->foo = $foo; -unset($foo); -unset($bar); -var_dump(gc_collect_cycles()); -?> ---EXPECT-- -int(6) diff --git a/Zend/tests/gc_032.phpt b/Zend/tests/gc_032.phpt index cd30ed7cb6..90c30f7c16 100644 --- a/Zend/tests/gc_032.phpt +++ b/Zend/tests/gc_032.phpt @@ -7,35 +7,25 @@ zend.enable_gc=1 $a = array(); $b =& $a; $a[0] = $a; -debug_zval_dump($a); +var_dump($a); $a = array(array()); $b =& $a; $a[0][0] = $a; -debug_zval_dump($a); +var_dump($a); ?> ---EXPECTF-- -array(1) refcount(%d){ +--EXPECT-- +array(1) { [0]=> - array(1) refcount(%d){ - [0]=> - array(1) refcount(%d){ - [0]=> - *RECURSION* - } + array(0) { } } -array(1) refcount(%d){ +array(1) { [0]=> - array(1) refcount(%d){ + array(1) { [0]=> - array(1) refcount(%d){ + array(1) { [0]=> - array(1) refcount(%d){ - [0]=> - array(1) refcount(%d){ - [0]=> - *RECURSION* - } + array(0) { } } } diff --git a/Zend/tests/gc_036.phpt b/Zend/tests/gc_036.phpt new file mode 100644 index 0000000000..67f9a45465 --- /dev/null +++ b/Zend/tests/gc_036.phpt @@ -0,0 +1,19 @@ +--TEST-- +GC 036: Memleaks in self-referenced array +--INI-- +zend.enable_gc = 1 +--FILE-- +<?php +function &foo() { + $a = []; + $a[] =& $a; + return $a; +} +function bar() { + gc_collect_cycles(); +} +bar(foo()); +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/list/list_reference_001.phpt b/Zend/tests/list/list_reference_001.phpt new file mode 100644 index 0000000000..a173c7103e --- /dev/null +++ b/Zend/tests/list/list_reference_001.phpt @@ -0,0 +1,88 @@ +--TEST-- +"Reference Unpacking - General" list() +--FILE-- +<?php +$arr = array(1, array(2)); +list(&$a, list(&$b)) = $arr; +var_dump($a, $b); +var_dump($arr); + +$arr = array(1, array(2)); +list($a, &$b) = $arr; +var_dump($arr); + +$arr = array(1, array(2)); +[&$a, [&$b]] = $arr; +var_dump($a, $b); +var_dump($arr); + +$arr = array(1, array(2)); +[&$a, [&$b], &$c] = $arr; +var_dump($a, $b, $c); +var_dump($arr); + +$arr = array("one" => 1, "two" => array(2)); +["one" => &$a, "two" => [&$b], "three" => &$c] = $arr; +var_dump($a, $b, $c); +var_dump($arr); +?> +--EXPECTF-- +int(1) +int(2) +array(2) { + [0]=> + &int(1) + [1]=> + array(1) { + [0]=> + &int(2) + } +} +array(2) { + [0]=> + int(1) + [1]=> + &array(1) { + [0]=> + int(2) + } +} +int(1) +int(2) +array(2) { + [0]=> + &int(1) + [1]=> + array(1) { + [0]=> + &int(2) + } +} +int(1) +int(2) +NULL +array(3) { + [0]=> + &int(1) + [1]=> + array(1) { + [0]=> + &int(2) + } + [2]=> + &NULL +} +int(1) +int(2) +NULL +array(3) { + ["one"]=> + &int(1) + ["two"]=> + array(1) { + [0]=> + &int(2) + } + ["three"]=> + &NULL +} diff --git a/Zend/tests/list/list_reference_002.phpt b/Zend/tests/list/list_reference_002.phpt new file mode 100644 index 0000000000..32aad686d1 --- /dev/null +++ b/Zend/tests/list/list_reference_002.phpt @@ -0,0 +1,20 @@ +--TEST-- +"Reference Unpacking - New Reference" list() +--FILE-- +<?php +$arr = array(new stdclass); +list(&$a, &$b) = $arr; +var_dump($a, $b); +var_dump($arr); +?> +--EXPECTF-- +object(stdClass)#%d (0) { +} +NULL +array(2) { + [0]=> + &object(stdClass)#%d (0) { + } + [1]=> + &NULL +} diff --git a/Zend/tests/list/list_reference_003.phpt b/Zend/tests/list/list_reference_003.phpt new file mode 100644 index 0000000000..9c903407d5 --- /dev/null +++ b/Zend/tests/list/list_reference_003.phpt @@ -0,0 +1,73 @@ +--TEST-- +"Reference Unpacking - From Functions" list() +--FILE-- +<?php +$arr = [1, 2]; +function no_ref($a) { + return $a; +} + +function no_ref_by_ref(&$a) { + return $a; +} + +function &ref_return(&$a) { + return $a; +} + +function &ref_return_global() { + global $arr; + return $arr; +} + +$a = [1, 2]; +[&$var] = no_ref($a); +var_dump($var); +var_dump($a); + +$a = [1, 2]; +[&$var] = no_ref_by_ref($a); +var_dump($var); +var_dump($a); + +$a = [1, 2]; +[&$var] = ref_return($a); +var_dump($var); +var_dump($a); + +[,&$var] = ref_return_global(); +var_dump($var); +var_dump($arr); +?> +--EXPECTF-- +Notice: Attempting to set reference to non referenceable value in %s on line %d +int(1) +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} + +Notice: Attempting to set reference to non referenceable value in %s on line %d +int(1) +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +int(1) +array(2) { + [0]=> + &int(1) + [1]=> + int(2) +} +int(2) +array(2) { + [0]=> + int(1) + [1]=> + &int(2) +} diff --git a/Zend/tests/list/list_reference_004.phpt b/Zend/tests/list/list_reference_004.phpt new file mode 100644 index 0000000000..fc9955e28a --- /dev/null +++ b/Zend/tests/list/list_reference_004.phpt @@ -0,0 +1,28 @@ +--TEST-- +"Reference Unpacking - Foreach" list() +--FILE-- +<?php +$coords = array(array(1, 2), array(3, 4)); +foreach ($coords as [&$x, $y]) { + $x++; + $y++; +} +var_dump($coords); +?> +--EXPECTF-- +array(2) { + [0]=> + array(2) { + [0]=> + int(2) + [1]=> + int(2) + } + [1]=> + array(2) { + [0]=> + &int(4) + [1]=> + int(4) + } +} diff --git a/Zend/tests/list/list_reference_005.phpt b/Zend/tests/list/list_reference_005.phpt new file mode 100644 index 0000000000..397f9013b5 --- /dev/null +++ b/Zend/tests/list/list_reference_005.phpt @@ -0,0 +1,73 @@ +--TEST-- +"Reference Unpacking - Class Property and Methods" list() +--FILE-- +<?php +class A { + public $a = [['hello']]; + public $b = ['world']; + + public function getVar() { + return $this->a; + } + + public function &getVarRef() { + return $this->a; + } +} + +class B { + static $a = [['world']]; +} + +$a = new A(); +[&$var] = $a->a; +[&$var_too] = $a->b; +var_dump($a->a); +var_dump($a->b); + +$a = new A(); +[&$var] = $a->getVar(); +var_dump($a->a); + +$a = new A(); +[&$var] = $a->getVarRef(); +var_dump($a->a); + +[&$var] = B::$a; +var_dump(B::$a); +?> +--EXPECTF-- +array(1) { + [0]=> + &array(1) { + [0]=> + string(5) "hello" + } +} +array(1) { + [0]=> + &string(5) "world" +} + +Notice: Attempting to set reference to non referenceable value in %s on line %d +array(1) { + [0]=> + array(1) { + [0]=> + string(5) "hello" + } +} +array(1) { + [0]=> + &array(1) { + [0]=> + string(5) "hello" + } +} +array(1) { + [0]=> + &array(1) { + [0]=> + string(5) "world" + } +} diff --git a/Zend/tests/list/list_reference_006.phpt b/Zend/tests/list/list_reference_006.phpt new file mode 100644 index 0000000000..f85edf04a4 --- /dev/null +++ b/Zend/tests/list/list_reference_006.phpt @@ -0,0 +1,58 @@ +--TEST-- +"Reference Unpacking - Class ArrayAccess No Reference" list() +--FILE-- +<?php +class StorageNoRef implements ArrayAccess { + private $s = []; + function __construct(array $a) { $this->s = $a; } + function offsetSet ($k, $v) { $this->s[$k] = $v; } + function offsetGet ($k) { return $this->s[$k]; } + function offsetExists ($k) { return isset($this->s[$k]); } + function offsetUnset ($k) { unset($this->s[$k]); } +} + +$a = new StorageNoRef([1, 2]); +list(&$one, $two) = $a; +var_dump($a); + +$a = new StorageNoRef([1, 2]); +list(,,list($var)) = $a; +var_dump($a); + +$a = new StorageNoRef(['one' => 1, 'two' => 2]); +['one' => &$one, 'two' => $two] = $a; +var_dump($a); +?> +--EXPECTF-- +Notice: Indirect modification of overloaded element of %s has no effect in %s on line %d +object(StorageNoRef)#1 (1) { + ["s":"StorageNoRef":private]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } +} + +Notice: Undefined offset: 2 in %s on line %d +object(StorageNoRef)#2 (1) { + ["s":"StorageNoRef":private]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } +} + +Notice: Indirect modification of overloaded element of %s has no effect in %s on line %d +object(StorageNoRef)#1 (1) { + ["s":"StorageNoRef":private]=> + array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) + } +} diff --git a/Zend/tests/list/list_reference_007.phpt b/Zend/tests/list/list_reference_007.phpt new file mode 100644 index 0000000000..51f1cac496 --- /dev/null +++ b/Zend/tests/list/list_reference_007.phpt @@ -0,0 +1,75 @@ +--TEST-- +"Reference Unpacking - Class ArrayAccess With Reference" list() +--FILE-- +<?php + +class StorageRef implements ArrayAccess { + private $s = []; + function __construct(array $a) { $this->s = $a; } + function offsetSet ($k, $v) { $this->s[$k] = $v; } + function &offsetGet ($k) { return $this->s[$k]; } + function offsetExists ($k) { return isset($this->s[$k]); } + function offsetUnset ($k) { unset($this->s[$k]); } +} + +$a = new StorageRef([1, 2]); +list(&$one, $two) = $a; +var_dump($a); + +$a = new StorageRef([1, 2]); +list(,,list($var)) = $a; +var_dump($a); + +$a = new StorageRef([1, 2]); +list(,,list(&$var)) = $a; +var_dump($a); + +$a = new StorageRef(['one' => 1, 'two' => 2]); +['one' => &$one, 'two' => $two] = $a; +var_dump($a); + +?> +--EXPECTF-- +object(StorageRef)#1 (1) { + ["s":"StorageRef":private]=> + array(2) { + [0]=> + &int(1) + [1]=> + int(2) + } +} +object(StorageRef)#2 (1) { + ["s":"StorageRef":private]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + NULL + } +} +object(StorageRef)#1 (1) { + ["s":"StorageRef":private]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + array(1) { + [0]=> + &NULL + } + } +} +object(StorageRef)#2 (1) { + ["s":"StorageRef":private]=> + array(2) { + ["one"]=> + &int(1) + ["two"]=> + int(2) + } +} diff --git a/Zend/tests/list/list_reference_008.phpt b/Zend/tests/list/list_reference_008.phpt new file mode 100644 index 0000000000..9c754a698d --- /dev/null +++ b/Zend/tests/list/list_reference_008.phpt @@ -0,0 +1,68 @@ +--TEST-- +"Reference Unpacking - Oddities" list() +--FILE-- +<?php +$a = 1; +$b =& $a; +$arr = [&$a, &$b]; +list(&$a, &$b) = $arr; +var_dump($a, $b, $arr); +$b++; +var_dump($a, $b, $arr); +unset($a, $b, $arr); + +/* + * $a is first set as a reference to the 0'th elem, '1' + * $a is then set to the value of the 1'st elem, '2' + * $arr would look like, [2,2] + * Increment $a, and it should be [3, 2] + */ +$arr = [1, 2]; +list(&$a, $a) = $arr; +var_dump($a); +$a++; +var_dump($arr); +unset($a, $arr); + +/* + * We do not allow references to the same variable of rhs. + */ +$a = [1, 2]; +$ref =& $a; +list(&$a, &$b) = $a; +var_dump($a, $b); +$a++; $b++; +var_dump($ref); +?> +--EXPECTF-- +int(1) +int(1) +array(2) { + [0]=> + &int(1) + [1]=> + &int(1) +} +int(2) +int(2) +array(2) { + [0]=> + &int(2) + [1]=> + &int(2) +} +int(2) +array(2) { + [0]=> + &int(3) + [1]=> + int(2) +} +int(1) +int(2) +array(2) { + [0]=> + &int(2) + [1]=> + &int(3) +} diff --git a/Zend/tests/list/list_reference_009.phpt b/Zend/tests/list/list_reference_009.phpt new file mode 100644 index 0000000000..f0adc1f088 --- /dev/null +++ b/Zend/tests/list/list_reference_009.phpt @@ -0,0 +1,47 @@ +--TEST-- +"Reference Unpacking - VM Safety" list() +--FILE-- +<?php +$ary = [[0, 1]]; +[[ + 0 => &$a, + ($ary["foo"] = 1) => &$b +]] = $ary; + +var_dump($ary, $a, $b); +unset($ary, $a, $b); + +$ary = [[0, 1]]; +[ + 0 => &$a, + ($ary["foo"] = 1) => &$b +] = $ary[0]; +var_dump($ary, $a, $b); +?> +--EXPECTF-- +array(2) { + [0]=> + array(2) { + [0]=> + &int(0) + [1]=> + &int(1) + } + ["foo"]=> + int(1) +} +int(0) +int(1) +array(2) { + [0]=> + array(2) { + [0]=> + &int(0) + [1]=> + &int(1) + } + ["foo"]=> + int(1) +} +int(0) +int(1) diff --git a/Zend/tests/list/list_reference_010.phpt b/Zend/tests/list/list_reference_010.phpt new file mode 100644 index 0000000000..8ceb344a33 --- /dev/null +++ b/Zend/tests/list/list_reference_010.phpt @@ -0,0 +1,8 @@ +--TEST-- +"Reference Unpacking - Compile Error (scalar)" list() +--FILE-- +<?php +list(&$foo) = [42]; +?> +--EXPECTF-- +Fatal error: Cannot assign reference to non referencable value in %s on line %d diff --git a/Zend/tests/list/list_reference_011.phpt b/Zend/tests/list/list_reference_011.phpt new file mode 100644 index 0000000000..405f34f227 --- /dev/null +++ b/Zend/tests/list/list_reference_011.phpt @@ -0,0 +1,9 @@ +--TEST-- +"Reference Unpacking - Compile Error (const)" list() +--FILE-- +<?php +const FOO = 10; +[&$f] = FOO; +?> +--EXPECTF-- +Fatal error: Cannot assign reference to non referencable value in %s on line %d diff --git a/Zend/tests/list_009.phpt b/Zend/tests/list_009.phpt deleted file mode 100644 index c28ca8000a..0000000000 --- a/Zend/tests/list_009.phpt +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -list with by-reference assignment should fail ---FILE-- -<?php - -$a = [1]; -[&$foo] = $a; -$foo = 2; - -var_dump($a); - -?> ---EXPECTF-- -Fatal error: [] and list() assignments cannot be by reference in %s on line %d diff --git a/Zend/tests/traits/bug63911.phpt b/Zend/tests/traits/bug63911.phpt new file mode 100644 index 0000000000..72892cdd34 --- /dev/null +++ b/Zend/tests/traits/bug63911.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #63911 (Ignore conflicting trait methods originationg from identical sub traits) +--FILE-- +<?php +trait A +{ + public function a(){ + echo 'Done'; + } +} +trait B +{ + use A; +} +trait C +{ + use A; +} +class D +{ + use B, C; +} + +(new D)->a(); +--EXPECT-- +Done diff --git a/Zend/tests/traits/bug74922.phpt b/Zend/tests/traits/bug74922.phpt new file mode 100644 index 0000000000..16272b8f68 --- /dev/null +++ b/Zend/tests/traits/bug74922.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #74922 (Composed class has fatal error with duplicate, equal const properties) +--FILE-- +<?php + +const VALUE = true; + +trait Foo {public $var = VALUE;} +trait Bar {public $var = VALUE;} +class Baz {use Foo, Bar;} + +echo "DONE"; + +?> +--EXPECT-- +DONE diff --git a/Zend/tests/traits/bug74922a.phpt b/Zend/tests/traits/bug74922a.phpt new file mode 100644 index 0000000000..40617bcdc8 --- /dev/null +++ b/Zend/tests/traits/bug74922a.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #74922 (Composed class has fatal error with duplicate, equal const properties) +--FILE-- +<?php + +const VALUE = true; + +trait Foo {public $var = VALUE;} +trait Bar {public $var = true;} +class Baz {use Foo, Bar;} + +echo "DONE"; + +?> +--EXPECT-- +DONE diff --git a/Zend/tests/traits/bug74922b.inc b/Zend/tests/traits/bug74922b.inc new file mode 100644 index 0000000000..b64ee21985 --- /dev/null +++ b/Zend/tests/traits/bug74922b.inc @@ -0,0 +1,9 @@ +<?php + +namespace Bug74922; + +const FOO = 'foo'; + +trait T1 { + public $var = FOO; +} diff --git a/Zend/tests/traits/bug74922b.phpt b/Zend/tests/traits/bug74922b.phpt new file mode 100644 index 0000000000..9a0f23546a --- /dev/null +++ b/Zend/tests/traits/bug74922b.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #74922 (Composed class has fatal error with duplicate, equal const properties) +--FILE-- +<?php + +require('bug74922b.inc'); + +trait T2 {public $var = Bug74922\FOO;} +class Baz {use Bug74922\T1, T2;} + +echo "DONE"; + +?> +--EXPECT-- +DONE diff --git a/Zend/tests/traits/bug74922c.phpt b/Zend/tests/traits/bug74922c.phpt new file mode 100644 index 0000000000..367bbf4eab --- /dev/null +++ b/Zend/tests/traits/bug74922c.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #74922 (Composed class has fatal error with duplicate, equal const properties) +--FILE-- +<?php + +trait T { + public $x = self::X; +} +trait T2 { + public $x = self::X; +} +class C { + use T, T2; + const X = 42; +} +var_dump((new C)->x); + +?> +--EXPECT-- +int(42) diff --git a/Zend/zend.c b/Zend/zend.c index d7e00e46b2..34b5e7416d 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -75,13 +75,18 @@ ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint3 void (*zend_printf_to_smart_string)(smart_string *buf, const char *format, va_list ap); void (*zend_printf_to_smart_str)(smart_str *buf, const char *format, va_list ap); ZEND_API char *(*zend_getenv)(char *name, size_t name_len); -ZEND_API zend_string *(*zend_resolve_path)(const char *filename, int filename_len); +ZEND_API zend_string *(*zend_resolve_path)(const char *filename, size_t filename_len); +ZEND_API int (*zend_post_startup_cb)(void) = NULL; void (*zend_on_timeout)(int seconds); static void (*zend_message_dispatcher_p)(zend_long message, const void *data); static zval *(*zend_get_configuration_directive_p)(zend_string *name); +#if ZEND_RC_DEBUG +ZEND_API zend_bool zend_rc_debug = 0; +#endif + static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */ { if (!new_value) { @@ -130,7 +135,7 @@ static ZEND_INI_MH(OnUpdateAssertions) /* {{{ */ p = (zend_long *) (base+(size_t) mh_arg1); - val = zend_atol(ZSTR_VAL(new_value), (int)ZSTR_LEN(new_value)); + val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value)); if (stage != ZEND_INI_STAGE_STARTUP && stage != ZEND_INI_STAGE_SHUTDOWN && @@ -197,6 +202,18 @@ ZEND_API size_t zend_spprintf(char **message, size_t max_len, const char *format } /* }}} */ +ZEND_API size_t zend_spprintf_unchecked(char **message, size_t max_len, const char *format, ...) /* {{{ */ +{ + va_list arg; + size_t len; + + va_start(arg, format); + len = zend_vspprintf(message, max_len, format, arg); + va_end(arg); + return len; +} +/* }}} */ + ZEND_API zend_string *zend_vstrpprintf(size_t max_len, const char *format, va_list ap) /* {{{ */ { smart_str buf = {0}; @@ -228,6 +245,18 @@ ZEND_API zend_string *zend_strpprintf(size_t max_len, const char *format, ...) / } /* }}} */ +ZEND_API zend_string *zend_strpprintf_unchecked(size_t max_len, const char *format, ...) /* {{{ */ +{ + va_list arg; + zend_string *str; + + va_start(arg, format); + str = zend_vstrpprintf(max_len, format, arg); + va_end(arg); + return str; +} +/* }}} */ + static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent); static void print_hash(smart_str *buf, HashTable *ht, int indent, zend_bool is_object) /* {{{ */ @@ -309,7 +338,7 @@ ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy) /* {{{ */ if (Z_TYPE_P(expr) == IS_STRING) { return 0; } else { - ZVAL_STR(expr_copy, _zval_get_string_func(expr)); + ZVAL_STR(expr_copy, zval_get_string_func(expr)); return 1; } } @@ -317,14 +346,15 @@ ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy) /* {{{ */ ZEND_API size_t zend_print_zval(zval *expr, int indent) /* {{{ */ { - zend_string *str = zval_get_string(expr); + zend_string *tmp_str; + zend_string *str = zval_get_tmp_string(expr, &tmp_str); size_t len = ZSTR_LEN(str); if (len != 0) { zend_write(ZSTR_VAL(str), len); } - zend_string_release(str); + zend_tmp_string_release(tmp_str); return len; } /* }}} */ @@ -334,16 +364,17 @@ ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */ switch (Z_TYPE_P(expr)) { case IS_ARRAY: ZEND_PUTS("Array ("); - if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr)) && - ++Z_ARRVAL_P(expr)->u.v.nApplyCount>1) { - ZEND_PUTS(" *RECURSION*"); - Z_ARRVAL_P(expr)->u.v.nApplyCount--; - return; + if (Z_REFCOUNTED_P(expr)) { + if (Z_IS_RECURSIVE_P(expr)) { + ZEND_PUTS(" *RECURSION*"); + return; + } + Z_PROTECT_RECURSION_P(expr); } print_flat_hash(Z_ARRVAL_P(expr)); ZEND_PUTS(")"); - if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr))) { - Z_ARRVAL_P(expr)->u.v.nApplyCount--; + if (Z_REFCOUNTED_P(expr)) { + Z_UNPROTECT_RECURSION_P(expr); } break; case IS_OBJECT: @@ -353,7 +384,7 @@ ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */ zend_printf("%s Object (", ZSTR_VAL(class_name)); zend_string_release(class_name); - if (Z_OBJ_APPLY_COUNT_P(expr) > 0) { + if (Z_IS_RECURSIVE_P(expr)) { ZEND_PUTS(" *RECURSION*"); return; } @@ -362,9 +393,9 @@ ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */ properties = Z_OBJPROP_P(expr); } if (properties) { - Z_OBJ_INC_APPLY_COUNT_P(expr); + Z_PROTECT_RECURSION_P(expr); print_flat_hash(properties); - Z_OBJ_DEC_APPLY_COUNT_P(expr); + Z_UNPROTECT_RECURSION_P(expr); } ZEND_PUTS(")"); break; @@ -384,15 +415,16 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /* switch (Z_TYPE_P(expr)) { case IS_ARRAY: smart_str_appends(buf, "Array\n"); - if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr)) && - ++Z_ARRVAL_P(expr)->u.v.nApplyCount>1) { - smart_str_appends(buf, " *RECURSION*"); - Z_ARRVAL_P(expr)->u.v.nApplyCount--; - return; + if (Z_REFCOUNTED_P(expr)) { + if (Z_IS_RECURSIVE_P(expr)) { + smart_str_appends(buf, " *RECURSION*"); + return; + } + Z_PROTECT_RECURSION_P(expr); } print_hash(buf, Z_ARRVAL_P(expr), indent, 0); - if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr))) { - Z_ARRVAL_P(expr)->u.v.nApplyCount--; + if (Z_REFCOUNTED_P(expr)) { + Z_UNPROTECT_RECURSION_P(expr); } break; case IS_OBJECT: @@ -405,7 +437,7 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /* zend_string_release(class_name); smart_str_appends(buf, " Object\n"); - if (Z_OBJ_APPLY_COUNT_P(expr) > 0) { + if (Z_IS_RECURSIVE_P(expr)) { smart_str_appends(buf, " *RECURSION*"); return; } @@ -413,9 +445,9 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /* break; } - Z_OBJ_INC_APPLY_COUNT_P(expr); + Z_PROTECT_RECURSION_P(expr); print_hash(buf, properties, indent, 1); - Z_OBJ_DEC_APPLY_COUNT_P(expr); + Z_UNPROTECT_RECURSION_P(expr); if (is_temp) { zend_hash_destroy(properties); @@ -429,9 +461,12 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /* case IS_REFERENCE: zend_print_zval_r_to_buf(buf, Z_REFVAL_P(expr), indent); break; + case IS_STRING: + smart_str_append(buf, Z_STR_P(expr)); + break; default: { - zend_string *str = zval_get_string(expr); + zend_string *str = zval_get_string_func(expr); smart_str_append(buf, str); zend_string_release(str); } @@ -831,7 +866,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) / zend_interned_strings_init(); zend_startup_builtin_functions(); zend_register_standard_constants(); - zend_register_auto_global(zend_string_init("GLOBALS", sizeof("GLOBALS") - 1, 1), 1, php_auto_globals_create_globals); + zend_register_auto_global(zend_string_init_interned("GLOBALS", sizeof("GLOBALS") - 1, 1), 1, php_auto_globals_create_globals); #ifndef ZTS zend_init_rsrc_plist(); @@ -866,7 +901,7 @@ void zend_register_standard_ini_entries(void) /* {{{ */ /* Unlink the global (r/o) copies of the class, function and constant tables, * and use a fresh r/w copy for the startup thread */ -void zend_post_startup(void) /* {{{ */ +int zend_post_startup(void) /* {{{ */ { #ifdef ZTS zend_encoding **script_encoding_list; @@ -896,6 +931,17 @@ void zend_post_startup(void) /* {{{ */ global_persistent_list = &EG(persistent_list); zend_copy_ini_directives(); #endif + + if (zend_post_startup_cb) { + int (*cb)(void) = zend_post_startup_cb; + + zend_post_startup_cb = NULL; + if (cb() != SUCCESS) { + return FAILURE; + } + } + + return SUCCESS; } /* }}} */ @@ -930,10 +976,6 @@ void zend_shutdown(void) /* {{{ */ GLOBAL_CONSTANTS_TABLE = NULL; #endif zend_destroy_rsrc_list_dtors(); - -#ifndef ZTS - zend_interned_strings_dtor(); -#endif } /* }}} */ diff --git a/Zend/zend.h b/Zend/zend.h index 1a6fe6c0c3..cf6bd37d5d 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -22,7 +22,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "3.2.0" +#define ZEND_VERSION "3.3.0-dev" #define ZEND_ENGINE_3 @@ -189,7 +189,7 @@ typedef struct _zend_utility_functions { void (*printf_to_smart_string_function)(smart_string *buf, const char *format, va_list ap); void (*printf_to_smart_str_function)(smart_str *buf, const char *format, va_list ap); char *(*getenv_function)(char *name, size_t name_len); - zend_string *(*resolve_path_function)(const char *filename, int filename_len); + zend_string *(*resolve_path_function)(const char *filename, size_t filename_len); } zend_utility_functions; typedef struct _zend_utility_values { @@ -222,7 +222,7 @@ BEGIN_EXTERN_C() int zend_startup(zend_utility_functions *utility_functions, char **extensions); void zend_shutdown(void); void zend_register_standard_ini_entries(void); -void zend_post_startup(void); +int zend_post_startup(void); void zend_set_utility_values(zend_utility_values *utility_values); ZEND_API ZEND_COLD void _zend_bailout(const char *filename, uint32_t lineno); @@ -232,6 +232,11 @@ ZEND_API size_t zend_spprintf(char **message, size_t max_len, const char *format ZEND_API zend_string *zend_vstrpprintf(size_t max_len, const char *format, va_list ap); ZEND_API zend_string *zend_strpprintf(size_t max_len, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); +/* Same as zend_spprintf and zend_strpprintf, without checking of format validity. + * For use with custom printf specifiers such as %H. */ +ZEND_API size_t zend_spprintf_unchecked(char **message, size_t max_len, const char *format, ...); +ZEND_API zend_string *zend_strpprintf_unchecked(size_t max_len, const char *format, ...); + ZEND_API char *get_zend_version(void); ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy); ZEND_API size_t zend_print_zval(zval *expr, int indent); @@ -269,7 +274,8 @@ extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file extern void (*zend_printf_to_smart_string)(smart_string *buf, const char *format, va_list ap); extern void (*zend_printf_to_smart_str)(smart_str *buf, const char *format, va_list ap); extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len); -extern ZEND_API zend_string *(*zend_resolve_path)(const char *filename, int filename_len); +extern ZEND_API zend_string *(*zend_resolve_path)(const char *filename, size_t filename_len); +extern ZEND_API int (*zend_post_startup_cb)(void); ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 516753fdf7..357368f88d 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -45,67 +45,6 @@ static zend_module_entry **module_post_deactivate_handlers; static zend_class_entry **class_cleanup_handlers; -/* this function doesn't check for too many parameters */ -ZEND_API int zend_get_parameters(int ht, int param_count, ...) /* {{{ */ -{ - int arg_count; - va_list ptr; - zval **param, *param_ptr; - - param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1); - arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data)); - - if (param_count>arg_count) { - return FAILURE; - } - - va_start(ptr, param_count); - - while (param_count-->0) { - param = va_arg(ptr, zval **); - if (!Z_ISREF_P(param_ptr) && Z_REFCOUNT_P(param_ptr) > 1) { - zval new_tmp; - - ZVAL_DUP(&new_tmp, param_ptr); - Z_DELREF_P(param_ptr); - ZVAL_COPY_VALUE(param_ptr, &new_tmp); - } - *param = param_ptr; - param_ptr++; - } - va_end(ptr); - - return SUCCESS; -} -/* }}} */ - -/* Zend-optimized Extended functions */ -/* this function doesn't check for too many parameters */ -ZEND_API int zend_get_parameters_ex(int param_count, ...) /* {{{ */ -{ - int arg_count; - va_list ptr; - zval **param, *param_ptr; - - param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1); - arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data)); - - if (param_count>arg_count) { - return FAILURE; - } - - va_start(ptr, param_count); - while (param_count-->0) { - param = va_arg(ptr, zval **); - *param = param_ptr; - param_ptr++; - } - va_end(ptr); - - return SUCCESS; -} -/* }}} */ - ZEND_API int _zend_get_parameters_array_ex(int param_count, zval *argument_array) /* {{{ */ { zval *param_ptr; @@ -141,9 +80,7 @@ ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array) / } while (param_count-->0) { - if (Z_REFCOUNTED_P(param_ptr)) { - Z_ADDREF_P(param_ptr); - } + Z_TRY_ADDREF_P(param_ptr); zend_hash_next_index_insert_new(Z_ARRVAL_P(argument_array), param_ptr); param_ptr++; } @@ -1084,15 +1021,6 @@ ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args, zval *this } /* }}} */ -/* Argument parsing API -- andrei */ -ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC) /* {{{ */ -{ - ZVAL_NEW_ARR(arg); - _zend_hash_init(Z_ARRVAL_P(arg), size, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC); - return SUCCESS; -} -/* }}} */ - /* This function should be called after the constructor has been called * because it may call __set from the uninitialized object otherwise. */ ZEND_API void zend_merge_properties(zval *obj, HashTable *properties) /* {{{ */ @@ -1136,19 +1064,21 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */ #endif for (i = 0; i < class_type->default_static_members_count; i++) { p = &class_type->default_static_members_table[i]; - if (Z_ISREF_P(p) && - class_type->parent && - i < class_type->parent->default_static_members_count && - p == &class_type->parent->default_static_members_table[i] && - Z_TYPE(CE_STATIC_MEMBERS(class_type->parent)[i]) != IS_UNDEF - ) { - zval *q = &CE_STATIC_MEMBERS(class_type->parent)[i]; - - ZVAL_NEW_REF(q, q); - ZVAL_COPY_VALUE(&CE_STATIC_MEMBERS(class_type)[i], q); - Z_ADDREF_P(q); + if (Z_ISREF_P(p)) { + if (class_type->parent && + i < class_type->parent->default_static_members_count && + p == &class_type->parent->default_static_members_table[i] && + Z_TYPE(CE_STATIC_MEMBERS(class_type->parent)[i]) != IS_UNDEF + ) { + zval *q = &CE_STATIC_MEMBERS(class_type->parent)[i]; + + ZVAL_NEW_REF(q, q); + ZVAL_COPY(&CE_STATIC_MEMBERS(class_type)[i], q); + } else { + ZVAL_COPY_OR_DUP(&CE_STATIC_MEMBERS(class_type)[i], Z_REFVAL_P(p)); + } } else { - ZVAL_DUP(&CE_STATIC_MEMBERS(class_type)[i], p); + ZVAL_COPY_OR_DUP(&CE_STATIC_MEMBERS(class_type)[i], p); } } } else { @@ -1159,7 +1089,7 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */ ZEND_HASH_FOREACH_PTR(&class_type->constants_table, c) { val = &c->value; - if (Z_CONSTANT_P(val)) { + if (Z_TYPE_P(val) == IS_CONSTANT_AST) { if (UNEXPECTED(zval_update_constant_ex(val, c->ce) != SUCCESS)) { return FAILURE; } @@ -1176,7 +1106,7 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */ val = (zval*)((char*)class_type->default_properties_table + prop_info->offset - OBJ_PROP_TO_OFFSET(0)); } ZVAL_DEREF(val); - if (Z_CONSTANT_P(val)) { + if (Z_TYPE_P(val) == IS_CONSTANT_AST) { if (UNEXPECTED(zval_update_constant_ex(val, ce) != SUCCESS)) { return FAILURE; } @@ -1200,15 +1130,19 @@ ZEND_API void object_properties_init(zend_object *object, zend_class_entry *clas zval *dst = object->properties_table; zval *end = src + class_type->default_properties_count; - do { -#if ZTS - ZVAL_DUP(dst, src); -#else - ZVAL_COPY(dst, src); -#endif - src++; - dst++; - } while (src != end); + if (UNEXPECTED(class_type->type == ZEND_INTERNAL_CLASS)) { + do { + ZVAL_COPY_OR_DUP(dst, src); + src++; + dst++; + } while (src != end); + } else { + do { + ZVAL_COPY(dst, src); + src++; + dst++; + } while (src != end); + } object->properties = NULL; } } @@ -1690,9 +1624,7 @@ ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value) /* {{{ */ } if (result) { - if (Z_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); - } + Z_TRY_ADDREF_P(result); return SUCCESS; } else { return FAILURE; @@ -2186,7 +2118,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio while (ptr->fname) { fname_len = strlen(ptr->fname); internal_function->handler = ptr->handler; - internal_function->function_name = zend_new_interned_string(zend_string_init(ptr->fname, fname_len, 1)); + internal_function->function_name = zend_string_init_interned(ptr->fname, fname_len, 1); internal_function->scope = scope; internal_function->prototype = NULL; if (ptr->flags) { @@ -2269,8 +2201,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio return FAILURE; } } - lowercase_name = zend_string_alloc(fname_len, 1); - zend_str_tolower_copy(ZSTR_VAL(lowercase_name), ptr->fname, fname_len); + lowercase_name = zend_string_tolower_ex(internal_function->function_name, 1); lowercase_name = zend_new_interned_string(lowercase_name); reg_function = malloc(sizeof(zend_internal_function)); memcpy(reg_function, &function, sizeof(zend_internal_function)); @@ -2316,7 +2247,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio class_name++; allow_null = 1; } - str = zend_new_interned_string(zend_string_init(class_name, strlen(class_name), 1)); + str = zend_string_init_interned(class_name, strlen(class_name), 1); new_arg_info[i].type = ZEND_TYPE_ENCODE_CLASS(str, allow_null); } } @@ -2578,7 +2509,7 @@ void module_destructor(zend_module_entry *module) /* {{{ */ } module->module_started=0; - if (module->functions) { + if (module->type == MODULE_TEMPORARY && module->functions) { zend_unregister_functions(module->functions, -1, NULL); } @@ -2704,7 +2635,7 @@ ZEND_API int zend_next_free_module(void) /* {{{ */ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class_entry, uint32_t ce_flags) /* {{{ */ { zend_class_entry *class_entry = malloc(sizeof(zend_class_entry)); - zend_string *lowercase_name = zend_string_alloc(ZSTR_LEN(orig_class_entry->name), 1); + zend_string *lowercase_name; *class_entry = *orig_class_entry; class_entry->type = ZEND_INTERNAL_CLASS; @@ -2716,7 +2647,7 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class zend_register_functions(class_entry, class_entry->info.internal.builtin_functions, &class_entry->function_table, MODULE_PERSISTENT); } - zend_str_tolower_copy(ZSTR_VAL(lowercase_name), ZSTR_VAL(orig_class_entry->name), ZSTR_LEN(class_entry->name)); + lowercase_name = zend_string_tolower_ex(orig_class_entry->name, 1); lowercase_name = zend_new_interned_string(lowercase_name); zend_hash_update_ptr(CG(class_table), lowercase_name, class_entry); zend_string_release(lowercase_name); @@ -2771,15 +2702,15 @@ ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *or } /* }}} */ -ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce) /* {{{ */ +ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce, int persistent) /* {{{ */ { zend_string *lcname; if (name[0] == '\\') { - lcname = zend_string_alloc(name_len-1, 1); + lcname = zend_string_alloc(name_len-1, persistent); zend_str_tolower_copy(ZSTR_VAL(lcname), name+1, name_len-1); } else { - lcname = zend_string_alloc(name_len, 1); + lcname = zend_string_alloc(name_len, persistent); zend_str_tolower_copy(ZSTR_VAL(lcname), name, name_len); } @@ -2810,9 +2741,7 @@ ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_lengt while (num_symbol_tables-- > 0) { symbol_table = va_arg(symbol_table_list, HashTable *); zend_hash_str_update(symbol_table, name, name_length, symbol); - if (Z_REFCOUNTED_P(symbol)) { - Z_ADDREF_P(symbol); - } + Z_TRY_ADDREF_P(symbol); } va_end(symbol_table_list); return SUCCESS; @@ -3308,7 +3237,7 @@ try_again: callable = Z_REFVAL_P(callable); goto try_again; default: - return zval_get_string(callable); + return zval_get_string_func(callable); } } /* }}} */ @@ -3571,9 +3500,7 @@ ZEND_API int zend_fcall_info_args_ex(zend_fcall_info *fci, zend_function *func, ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), arg) { if (func && !Z_ISREF_P(arg) && ARG_SHOULD_BE_SENT_BY_REF(func, n)) { ZVAL_NEW_REF(params, arg); - if (Z_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); - } + Z_TRY_ADDREF_P(arg); } else { ZVAL_COPY(params, arg); } @@ -3688,22 +3615,36 @@ ZEND_API const char *zend_get_module_version(const char *module_name) /* {{{ */ } /* }}} */ +static inline zend_string *zval_make_interned_string(zval *zv) /* {{{ */ +{ + ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING); + Z_STR_P(zv) = zend_new_interned_string(Z_STR_P(zv)); + if (ZSTR_IS_INTERNED(Z_STR_P(zv))) { + Z_TYPE_FLAGS_P(zv) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE); + } + return Z_STR_P(zv); +} + ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment) /* {{{ */ { zend_property_info *property_info, *property_info_ptr; if (ce->type == ZEND_INTERNAL_CLASS) { property_info = pemalloc(sizeof(zend_property_info), 1); - if ((access_type & ZEND_ACC_STATIC) || Z_CONSTANT_P(property)) { + if ((access_type & ZEND_ACC_STATIC) || Z_TYPE_P(property) == IS_CONSTANT_AST) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } } else { property_info = zend_arena_alloc(&CG(arena), sizeof(zend_property_info)); - if (Z_CONSTANT_P(property)) { + if (Z_TYPE_P(property) == IS_CONSTANT_AST) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } } + if (Z_TYPE_P(property) == IS_STRING && !ZSTR_IS_INTERNED(Z_STR_P(property))) { + zval_make_interned_string(property); + } + if (!(access_type & ZEND_ACC_PPP_MASK)) { access_type |= ZEND_ACC_PUBLIC; } @@ -3846,6 +3787,10 @@ ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *n "A class constant must not be called 'class'; it is reserved for class name fetching"); } + if (Z_TYPE_P(value) == IS_STRING && !ZSTR_IS_INTERNED(Z_STR_P(value))) { + zval_make_interned_string(value); + } + if (ce->type == ZEND_INTERNAL_CLASS) { c = pemalloc(sizeof(zend_class_constant), 1); } else { @@ -3855,7 +3800,7 @@ ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *n Z_ACCESS_FLAGS(c->value) = access_type; c->doc_comment = doc_comment; c->ce = ce; - if (Z_CONSTANT_P(value)) { + if (Z_TYPE_P(value) == IS_CONSTANT_AST) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } @@ -3872,9 +3817,12 @@ ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name, { int ret; - zend_string *key = zend_string_init(name, name_length, ce->type & ZEND_INTERNAL_CLASS); + zend_string *key; + if (ce->type == ZEND_INTERNAL_CLASS) { - key = zend_new_interned_string(key); + key = zend_string_init_interned(name, name_length, 1); + } else { + key = zend_string_init(name, name_length, 0); } ret = zend_declare_class_constant_ex(ce, key, value, ZEND_ACC_PUBLIC, NULL); zend_string_release(key); diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 865f5dd291..c05a527e6e 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -63,7 +63,7 @@ typedef struct _zend_fcall_info_cache { #define ZEND_FN(name) zif_##name #define ZEND_MN(name) zim_##name -#define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS) +#define ZEND_NAMED_FUNCTION(name) void ZEND_FASTCALL name(INTERNAL_FUNCTION_PARAMETERS) #define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name)) #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name)) @@ -193,9 +193,7 @@ typedef struct _zend_fcall_info_cache { #define INIT_OVERLOADED_CLASS_ENTRY_EX(class_container, class_name, class_name_len, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) \ { \ - zend_string *cl_name; \ - cl_name = zend_string_init(class_name, class_name_len, 1); \ - class_container.name = zend_new_interned_string(cl_name); \ + class_container.name = zend_string_init_interned(class_name, class_name_len, 1); \ INIT_CLASS_ENTRY_INIT_METHODS(class_container, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) \ } @@ -255,8 +253,6 @@ typedef struct _zend_fcall_info_cache { ZEND_API int zend_next_free_module(void); BEGIN_EXTERN_C() -ZEND_API int zend_get_parameters(int ht, int param_count, ...); -ZEND_API ZEND_ATTRIBUTE_DEPRECATED int zend_get_parameters_ex(int param_count, ...); ZEND_API int _zend_get_parameters_array_ex(int param_count, zval *argument_array); /* internal function to efficiently copy parameters when executing __call() */ @@ -304,12 +300,12 @@ ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *cla ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry); ZEND_API void zend_class_implements(zend_class_entry *class_entry, int num_interfaces, ...); -ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce); +ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce, int persistent); -#define zend_register_class_alias(name, ce) \ - zend_register_class_alias_ex(name, sizeof(name)-1, ce) -#define zend_register_ns_class_alias(ns, name, ce) \ - zend_register_class_alias_ex(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name))-1, ce) +#define zend_register_class_alias(name, ce, persistent) \ + zend_register_class_alias_ex(name, sizeof(name)-1, ce, persistent) +#define zend_register_ns_class_alias(ns, name, ce, persistent) \ + zend_register_class_alias_ex(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name))-1, ce, persistent) ZEND_API int zend_disable_function(char *function_name, size_t function_name_length); ZEND_API int zend_disable_class(char *class_name, size_t class_name_length); @@ -390,12 +386,11 @@ ZEND_API char *zend_get_type_by_const(int type); #define DLEXPORT #endif -#define array_init(arg) _array_init((arg), 0 ZEND_FILE_LINE_CC) -#define array_init_size(arg, size) _array_init((arg), (size) ZEND_FILE_LINE_CC) +#define array_init(arg) ZVAL_ARR((arg), zend_new_array(0)) +#define array_init_size(arg, size) ZVAL_ARR((arg), zend_new_array(size)) #define object_init(arg) _object_init((arg) ZEND_FILE_LINE_CC) #define object_init_ex(arg, ce) _object_init_ex((arg), (ce) ZEND_FILE_LINE_CC) #define object_and_properties_init(arg, ce, properties) _object_and_properties_init((arg), (ce), (properties) ZEND_FILE_LINE_CC) -ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC); ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC); ZEND_API int _object_init_ex(zval *arg, zend_class_entry *ce ZEND_FILE_LINE_DC); ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties ZEND_FILE_LINE_DC); @@ -762,6 +757,10 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(zend_bool throw_ #define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args) \ ZEND_PARSE_PARAMETERS_START_EX(0, min_num_args, max_num_args) +#define ZEND_PARSE_PARAMETERS_NONE() \ + ZEND_PARSE_PARAMETERS_START(0, 0) \ + ZEND_PARSE_PARAMETERS_END() + #define ZEND_PARSE_PARAMETERS_END_EX(failure) \ } while (0); \ if (UNEXPECTED(error_code != ZPP_ERROR_OK)) { \ @@ -828,7 +827,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(zend_bool throw_ #define Z_PARAM_ARRAY_OR_OBJECT_EX(dest, check_null, separate) \ Z_PARAM_ARRAY_OR_OBJECT_EX2(dest, check_null, separate, separate) -#define Z_PARAM_ARRAY_OR_OBJECT(dest, check_null, separate) \ +#define Z_PARAM_ARRAY_OR_OBJECT(dest) \ Z_PARAM_ARRAY_OR_OBJECT_EX(dest, 0, 0) /* old "b" */ @@ -1249,7 +1248,7 @@ static zend_always_inline int zend_parse_arg_array_ht(zval *arg, HashTable **des && Z_OBJ_P(arg)->properties && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(arg)->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(arg)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(Z_OBJ_P(arg)->properties)--; + GC_DELREF(Z_OBJ_P(arg)->properties); } Z_OBJ_P(arg)->properties = zend_array_dup(Z_OBJ_P(arg)->properties); } diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index d13213fec9..a780a7c05e 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -1423,97 +1423,130 @@ static size_t zend_mm_size(zend_mm_heap *heap, void *ptr ZEND_FILE_LINE_DC ZEND_ } } -static void *zend_mm_realloc_heap(zend_mm_heap *heap, void *ptr, size_t size, size_t copy_size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) +static zend_never_inline void *zend_mm_realloc_slow(zend_mm_heap *heap, void *ptr, size_t size, size_t copy_size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) +{ + void *ret; + +#if ZEND_MM_STAT + do { + size_t orig_peak = heap->peak; + size_t orig_real_peak = heap->real_peak; +#endif + ret = zend_mm_alloc_heap(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + memcpy(ret, ptr, copy_size); + zend_mm_free_heap(heap, ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); +#if ZEND_MM_STAT + heap->peak = MAX(orig_peak, heap->size); + heap->real_peak = MAX(orig_real_peak, heap->real_size); + } while (0); +#endif + return ret; +} + +static zend_never_inline void *zend_mm_realloc_huge(zend_mm_heap *heap, void *ptr, size_t size, size_t copy_size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { - size_t page_offset; size_t old_size; size_t new_size; - void *ret; #if ZEND_DEBUG size_t real_size; - zend_mm_debug_info *dbg; #endif - page_offset = ZEND_MM_ALIGNED_OFFSET(ptr, ZEND_MM_CHUNK_SIZE); - if (UNEXPECTED(page_offset == 0)) { - if (UNEXPECTED(ptr == NULL)) { - return zend_mm_alloc_heap(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); - } - old_size = zend_mm_get_huge_block_size(heap, ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + old_size = zend_mm_get_huge_block_size(heap, ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); #if ZEND_DEBUG - real_size = size; - size = ZEND_MM_ALIGNED_SIZE(size) + ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)); + real_size = size; + size = ZEND_MM_ALIGNED_SIZE(size) + ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)); #endif - if (size > ZEND_MM_MAX_LARGE_SIZE) { + if (size > ZEND_MM_MAX_LARGE_SIZE) { #if ZEND_DEBUG - size = real_size; + size = real_size; #endif #ifdef ZEND_WIN32 - /* On Windows we don't have ability to extend huge blocks in-place. - * We allocate them with 2MB size granularity, to avoid many - * reallocations when they are extended by small pieces - */ - new_size = ZEND_MM_ALIGNED_SIZE_EX(size, MAX(REAL_PAGE_SIZE, ZEND_MM_CHUNK_SIZE)); + /* On Windows we don't have ability to extend huge blocks in-place. + * We allocate them with 2MB size granularity, to avoid many + * reallocations when they are extended by small pieces + */ + new_size = ZEND_MM_ALIGNED_SIZE_EX(size, MAX(REAL_PAGE_SIZE, ZEND_MM_CHUNK_SIZE)); #else - new_size = ZEND_MM_ALIGNED_SIZE_EX(size, REAL_PAGE_SIZE); + new_size = ZEND_MM_ALIGNED_SIZE_EX(size, REAL_PAGE_SIZE); #endif - if (new_size == old_size) { + if (new_size == old_size) { #if ZEND_DEBUG - zend_mm_change_huge_block_size(heap, ptr, new_size, real_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + zend_mm_change_huge_block_size(heap, ptr, new_size, real_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); #else - zend_mm_change_huge_block_size(heap, ptr, new_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + zend_mm_change_huge_block_size(heap, ptr, new_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); #endif - return ptr; - } else if (new_size < old_size) { - /* unmup tail */ - if (zend_mm_chunk_truncate(heap, ptr, old_size, new_size)) { + return ptr; + } else if (new_size < old_size) { + /* unmup tail */ + if (zend_mm_chunk_truncate(heap, ptr, old_size, new_size)) { #if ZEND_MM_STAT || ZEND_MM_LIMIT - heap->real_size -= old_size - new_size; + heap->real_size -= old_size - new_size; #endif #if ZEND_MM_STAT - heap->size -= old_size - new_size; + heap->size -= old_size - new_size; #endif #if ZEND_DEBUG - zend_mm_change_huge_block_size(heap, ptr, new_size, real_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + zend_mm_change_huge_block_size(heap, ptr, new_size, real_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); #else - zend_mm_change_huge_block_size(heap, ptr, new_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + zend_mm_change_huge_block_size(heap, ptr, new_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); #endif - return ptr; - } - } else /* if (new_size > old_size) */ { + return ptr; + } + } else /* if (new_size > old_size) */ { #if ZEND_MM_LIMIT - if (UNEXPECTED(heap->real_size + (new_size - old_size) > heap->limit)) { - if (zend_mm_gc(heap) && heap->real_size + (new_size - old_size) <= heap->limit) { - /* pass */ - } else if (heap->overflow == 0) { + if (UNEXPECTED(heap->real_size + (new_size - old_size) > heap->limit)) { + if (zend_mm_gc(heap) && heap->real_size + (new_size - old_size) <= heap->limit) { + /* pass */ + } else if (heap->overflow == 0) { #if ZEND_DEBUG - zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted at %s:%d (tried to allocate %zu bytes)", heap->limit, __zend_filename, __zend_lineno, size); + zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted at %s:%d (tried to allocate %zu bytes)", heap->limit, __zend_filename, __zend_lineno, size); #else - zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)", heap->limit, size); + zend_mm_safe_error(heap, "Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)", heap->limit, size); #endif - return NULL; - } + return NULL; } + } #endif - /* try to map tail right after this block */ - if (zend_mm_chunk_extend(heap, ptr, old_size, new_size)) { + /* try to map tail right after this block */ + if (zend_mm_chunk_extend(heap, ptr, old_size, new_size)) { #if ZEND_MM_STAT || ZEND_MM_LIMIT - heap->real_size += new_size - old_size; + heap->real_size += new_size - old_size; #endif #if ZEND_MM_STAT - heap->real_peak = MAX(heap->real_peak, heap->real_size); - heap->size += new_size - old_size; - heap->peak = MAX(heap->peak, heap->size); + heap->real_peak = MAX(heap->real_peak, heap->real_size); + heap->size += new_size - old_size; + heap->peak = MAX(heap->peak, heap->size); #endif #if ZEND_DEBUG - zend_mm_change_huge_block_size(heap, ptr, new_size, real_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + zend_mm_change_huge_block_size(heap, ptr, new_size, real_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); #else - zend_mm_change_huge_block_size(heap, ptr, new_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + zend_mm_change_huge_block_size(heap, ptr, new_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); #endif - return ptr; - } + return ptr; } } + } + + return zend_mm_realloc_slow(heap, ptr, size, MIN(old_size, copy_size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); +} + +static zend_always_inline void *zend_mm_realloc_heap(zend_mm_heap *heap, void *ptr, size_t size, zend_bool use_copy_size, size_t copy_size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) +{ + size_t page_offset; + size_t old_size; + size_t new_size; + void *ret; +#if ZEND_DEBUG + zend_mm_debug_info *dbg; +#endif + + page_offset = ZEND_MM_ALIGNED_OFFSET(ptr, ZEND_MM_CHUNK_SIZE); + if (UNEXPECTED(page_offset == 0)) { + if (EXPECTED(ptr == NULL)) { + return _zend_mm_alloc(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + } else { + return zend_mm_realloc_huge(heap, ptr, size, copy_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + } } else { zend_mm_chunk *chunk = (zend_mm_chunk*)ZEND_MM_ALIGNED_BASE(ptr, ZEND_MM_CHUNK_SIZE); int page_num = (int)(page_offset / ZEND_MM_PAGE_SIZE); @@ -1527,21 +1560,56 @@ static void *zend_mm_realloc_heap(zend_mm_heap *heap, void *ptr, size_t size, si ZEND_MM_CHECK(chunk->heap == heap, "zend_mm_heap corrupted"); if (info & ZEND_MM_IS_SRUN) { int old_bin_num = ZEND_MM_SRUN_BIN_NUM(info); - old_size = bin_data_size[old_bin_num]; - if (size <= ZEND_MM_MAX_SMALL_SIZE) { - int bin_num = ZEND_MM_SMALL_SIZE_TO_BIN(size); - if (old_bin_num == bin_num) { -#if ZEND_DEBUG - dbg = zend_mm_get_debug_info(heap, ptr); - dbg->size = real_size; - dbg->filename = __zend_filename; - dbg->orig_filename = __zend_orig_filename; - dbg->lineno = __zend_lineno; - dbg->orig_lineno = __zend_orig_lineno; + + do { + old_size = bin_data_size[old_bin_num]; + + /* Check if requested size fits into current bin */ + if (size <= old_size) { + /* Check if truncation is necessary */ + if (old_bin_num > 0 && size < bin_data_size[old_bin_num - 1]) { + /* truncation */ + ret = zend_mm_alloc_small(heap, size, ZEND_MM_SMALL_SIZE_TO_BIN(size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + copy_size = use_copy_size ? MIN(size, copy_size) : size; + memcpy(ret, ptr, copy_size); + zend_mm_free_small(heap, ptr, old_bin_num); + } else { + /* reallocation in-place */ + ret = ptr; + } + } else if (size <= ZEND_MM_MAX_SMALL_SIZE) { + /* small extension */ + +#if ZEND_MM_STAT + do { + size_t orig_peak = heap->peak; + size_t orig_real_peak = heap->real_peak; +#endif + ret = zend_mm_alloc_small(heap, size, ZEND_MM_SMALL_SIZE_TO_BIN(size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + copy_size = use_copy_size ? MIN(old_size, copy_size) : old_size; + memcpy(ret, ptr, copy_size); + zend_mm_free_small(heap, ptr, old_bin_num); +#if ZEND_MM_STAT + heap->peak = MAX(orig_peak, heap->size); + heap->real_peak = MAX(orig_real_peak, heap->real_size); + } while (0); #endif - return ptr; + } else { + /* slow reallocation */ + break; } - } + +#if ZEND_DEBUG + dbg = zend_mm_get_debug_info(heap, ret); + dbg->size = real_size; + dbg->filename = __zend_filename; + dbg->orig_filename = __zend_orig_filename; + dbg->lineno = __zend_lineno; + dbg->orig_lineno = __zend_orig_lineno; +#endif + return ret; + } while (0); + } else /* if (info & ZEND_MM_IS_LARGE_RUN) */ { ZEND_MM_CHECK(ZEND_MM_ALIGNED_OFFSET(page_offset, ZEND_MM_PAGE_SIZE) == 0, "zend_mm_heap corrupted"); old_size = ZEND_MM_LRUN_PAGES(info) * ZEND_MM_PAGE_SIZE; @@ -1613,21 +1681,8 @@ static void *zend_mm_realloc_heap(zend_mm_heap *heap, void *ptr, size_t size, si #endif } - /* Naive reallocation */ -#if ZEND_MM_STAT - do { - size_t orig_peak = heap->peak; - size_t orig_real_peak = heap->real_peak; -#endif - ret = zend_mm_alloc_heap(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); - memcpy(ret, ptr, MIN(old_size, copy_size)); - zend_mm_free_heap(heap, ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#if ZEND_MM_STAT - heap->peak = MAX(orig_peak, heap->size); - heap->real_peak = MAX(orig_real_peak, heap->real_size); - } while (0); -#endif - return ret; + copy_size = MIN(old_size, copy_size); + return zend_mm_realloc_slow(heap, ptr, size, copy_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); } /*********************/ @@ -2277,12 +2332,12 @@ ZEND_API void ZEND_FASTCALL _zend_mm_free(zend_mm_heap *heap, void *ptr ZEND_FIL void* ZEND_FASTCALL _zend_mm_realloc(zend_mm_heap *heap, void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { - return zend_mm_realloc_heap(heap, ptr, size, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + return zend_mm_realloc_heap(heap, ptr, size, 0, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); } void* ZEND_FASTCALL _zend_mm_realloc2(zend_mm_heap *heap, void *ptr, size_t size, size_t copy_size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { - return zend_mm_realloc_heap(heap, ptr, size, copy_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + return zend_mm_realloc_heap(heap, ptr, size, 1, copy_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); } ZEND_API size_t ZEND_FASTCALL _zend_mm_block_size(zend_mm_heap *heap, void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) @@ -2459,7 +2514,7 @@ ZEND_API void* ZEND_FASTCALL _erealloc(void *ptr, size_t size ZEND_FILE_LINE_DC return AG(mm_heap)->custom_heap.std._realloc(ptr, size); } } - return zend_mm_realloc_heap(AG(mm_heap), ptr, size, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + return zend_mm_realloc_heap(AG(mm_heap), ptr, size, 0, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); } ZEND_API void* ZEND_FASTCALL _erealloc2(void *ptr, size_t size, size_t copy_size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) @@ -2472,7 +2527,7 @@ ZEND_API void* ZEND_FASTCALL _erealloc2(void *ptr, size_t size, size_t copy_size return AG(mm_heap)->custom_heap.std._realloc(ptr, size); } } - return zend_mm_realloc_heap(AG(mm_heap), ptr, size, copy_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + return zend_mm_realloc_heap(AG(mm_heap), ptr, size, 1, copy_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); } ZEND_API size_t ZEND_FASTCALL _zend_mem_block_size(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 772ba04e63..68db0e023f 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -25,6 +25,7 @@ #include "zend_language_parser.h" #include "zend_smart_str.h" #include "zend_exceptions.h" +#include "zend_constants.h" ZEND_API zend_ast_process_t zend_ast_process = NULL; @@ -72,6 +73,17 @@ ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) { return zend_ast_create_zval_with_lineno(zv, attr, CG(zend_lineno)); } +ZEND_API zend_ast *zend_ast_create_constant(zend_string *name, zend_ast_attr attr) { + zend_ast_zval *ast; + + ast = zend_ast_alloc(sizeof(zend_ast_zval)); + ast->kind = ZEND_AST_CONSTANT; + ast->attr = attr; + ZVAL_STR(&ast->val, name); + ast->val.u2.lineno = CG(zend_lineno); + return (zend_ast *) ast; +} + ZEND_API zend_ast *zend_ast_create_decl( zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment, zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3 @@ -276,25 +288,30 @@ ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *sc { zval *zv = zend_ast_get_zval(ast); - if (Z_OPT_CONSTANT_P(zv)) { - if (Z_TYPE_FLAGS_P(zv) & IS_TYPE_REFCOUNTED) { - if (UNEXPECTED(zval_update_constant_ex(zv, scope) != SUCCESS)) { - ret = FAILURE; - break; - } - ZVAL_COPY(result, zv); - } else { - ZVAL_COPY_VALUE(result, zv); - if (UNEXPECTED(zval_update_constant_ex(result, scope) != SUCCESS)) { - ret = FAILURE; - break; - } - } - } else { - ZVAL_COPY(result, zv); + ZVAL_COPY(result, zv); + break; + } + case ZEND_AST_CONSTANT: + { + zend_string *name = zend_ast_get_constant_name(ast); + zval *zv = zend_get_constant_ex(name, scope, ast->attr); + + if (UNEXPECTED(zv == NULL)) { + ZVAL_UNDEF(result); + ret = zend_use_undefined_constant(name, ast->attr, result); + break; } + ZVAL_COPY_OR_DUP(result, zv); break; } + case ZEND_AST_CONSTANT_CLASS: + ZEND_ASSERT(EG(current_execute_data)); + if (scope && scope->name) { + ZVAL_STR_COPY(result, scope->name); + } else { + ZVAL_EMPTY_STRING(result); + } + break; case ZEND_AST_AND: if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { ret = FAILURE; @@ -391,10 +408,15 @@ ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *sc } break; case ZEND_AST_ARRAY: - array_init(result); { uint32_t i; zend_ast_list *list = zend_ast_get_list(ast); + + if (!list->children) { + ZVAL_EMPTY_ARRAY(result); + break; + } + array_init(result); for (i = 0; i < list->children; i++) { zend_ast *elem = list->child[i]; if (elem->child[1]) { @@ -430,16 +452,8 @@ ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *sc zval_dtor(&op1); ret = FAILURE; } else { - zval tmp; + zend_fetch_dimension_const(result, &op1, &op2, (ast->attr == ZEND_DIM_IS) ? BP_VAR_IS : BP_VAR_R); - zend_fetch_dimension_const(&tmp, &op1, &op2, (ast->attr == ZEND_DIM_IS) ? BP_VAR_IS : BP_VAR_R); - - if (UNEXPECTED(Z_ISREF(tmp))) { - ZVAL_DUP(result, Z_REFVAL(tmp)); - } else { - ZVAL_DUP(result, &tmp); - } - zval_ptr_dtor(&tmp); zval_dtor(&op1); zval_dtor(&op2); } @@ -451,51 +465,109 @@ ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *sc return ret; } -ZEND_API zend_ast *zend_ast_copy(zend_ast *ast) +static size_t zend_ast_tree_size(zend_ast *ast) { - if (ast == NULL) { - return NULL; - } else if (ast->kind == ZEND_AST_ZVAL) { - zend_ast_zval *new = emalloc(sizeof(zend_ast_zval)); + size_t size; + + if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) { + size = sizeof(zend_ast_zval); + } else if (zend_ast_is_list(ast)) { + uint32_t i; + zend_ast_list *list = zend_ast_get_list(ast); + + size = zend_ast_list_size(list->children); + for (i = 0; i < list->children; i++) { + if (list->child[i]) { + size += zend_ast_tree_size(list->child[i]); + } + } + } else { + uint32_t i, children = zend_ast_get_num_children(ast); + + size = zend_ast_size(children); + for (i = 0; i < children; i++) { + if (ast->child[i]) { + size += zend_ast_tree_size(ast->child[i]); + } + } + } + return size; +} + +static void* zend_ast_tree_copy(zend_ast *ast, void *buf) +{ + if (ast->kind == ZEND_AST_ZVAL) { + zend_ast_zval *new = (zend_ast_zval*)buf; new->kind = ZEND_AST_ZVAL; new->attr = ast->attr; ZVAL_COPY(&new->val, zend_ast_get_zval(ast)); - return (zend_ast *) new; + buf = (void*)((char*)buf + sizeof(zend_ast_zval)); + } else if (ast->kind == ZEND_AST_CONSTANT) { + zend_ast_zval *new = (zend_ast_zval*)buf; + new->kind = ZEND_AST_CONSTANT; + new->attr = ast->attr; + ZVAL_STR_COPY(&new->val, zend_ast_get_constant_name(ast)); + buf = (void*)((char*)buf + sizeof(zend_ast_zval)); } else if (zend_ast_is_list(ast)) { zend_ast_list *list = zend_ast_get_list(ast); - zend_ast_list *new = emalloc(zend_ast_list_size(list->children)); + zend_ast_list *new = (zend_ast_list*)buf; uint32_t i; new->kind = list->kind; new->attr = list->attr; new->children = list->children; + buf = (void*)((char*)buf + zend_ast_list_size(list->children)); for (i = 0; i < list->children; i++) { - new->child[i] = zend_ast_copy(list->child[i]); + if (list->child[i]) { + new->child[i] = (zend_ast*)buf; + buf = zend_ast_tree_copy(list->child[i], buf); + } else { + new->child[i] = NULL; + } } - return (zend_ast *) new; } else { uint32_t i, children = zend_ast_get_num_children(ast); - zend_ast *new = emalloc(zend_ast_size(children)); + zend_ast *new = (zend_ast*)buf; new->kind = ast->kind; new->attr = ast->attr; + buf = (void*)((char*)buf + zend_ast_size(children)); for (i = 0; i < children; i++) { - new->child[i] = zend_ast_copy(ast->child[i]); + if (ast->child[i]) { + new->child[i] = (zend_ast*)buf; + buf = zend_ast_tree_copy(ast->child[i], buf); + } else { + new->child[i] = NULL; + } } - return new; } + return buf; +} + +ZEND_API zend_ast_ref *zend_ast_copy(zend_ast *ast) +{ + size_t tree_size; + zend_ast_ref *ref; + + ZEND_ASSERT(ast != NULL); + tree_size = zend_ast_tree_size(ast) + sizeof(zend_ast_ref); + ref = emalloc(tree_size); + zend_ast_tree_copy(ast, GC_AST(ref)); + GC_SET_REFCOUNT(ref, 1); + GC_TYPE_INFO(ref) = IS_CONSTANT_AST; + return ref; } -static void zend_ast_destroy_ex(zend_ast *ast, zend_bool free) { +ZEND_API void zend_ast_destroy(zend_ast *ast) { if (!ast) { return; } switch (ast->kind) { case ZEND_AST_ZVAL: - /* Destroy value without using GC: When opcache moves arrays into SHM it will - * free the zend_array structure, so references to it from outside the op array - * become invalid. GC would cause such a reference in the root buffer. */ zval_ptr_dtor_nogc(zend_ast_get_zval(ast)); break; + case ZEND_AST_CONSTANT: + zend_string_release(zend_ast_get_constant_name(ast)); + break; case ZEND_AST_FUNC_DECL: case ZEND_AST_CLOSURE: case ZEND_AST_METHOD: @@ -508,10 +580,10 @@ static void zend_ast_destroy_ex(zend_ast *ast, zend_bool free) { if (decl->doc_comment) { zend_string_release(decl->doc_comment); } - zend_ast_destroy_ex(decl->child[0], free); - zend_ast_destroy_ex(decl->child[1], free); - zend_ast_destroy_ex(decl->child[2], free); - zend_ast_destroy_ex(decl->child[3], free); + zend_ast_destroy(decl->child[0]); + zend_ast_destroy(decl->child[1]); + zend_ast_destroy(decl->child[2]); + zend_ast_destroy(decl->child[3]); break; } default: @@ -519,26 +591,15 @@ static void zend_ast_destroy_ex(zend_ast *ast, zend_bool free) { zend_ast_list *list = zend_ast_get_list(ast); uint32_t i; for (i = 0; i < list->children; i++) { - zend_ast_destroy_ex(list->child[i], free); + zend_ast_destroy(list->child[i]); } } else { uint32_t i, children = zend_ast_get_num_children(ast); for (i = 0; i < children; i++) { - zend_ast_destroy_ex(ast->child[i], free); + zend_ast_destroy(ast->child[i]); } } } - - if (free) { - efree(ast); - } -} - -ZEND_API void zend_ast_destroy(zend_ast *ast) { - zend_ast_destroy_ex(ast, 0); -} -ZEND_API void zend_ast_destroy_and_free(zend_ast *ast) { - zend_ast_destroy_ex(ast, 1); } ZEND_API void zend_ast_apply(zend_ast *ast, zend_ast_apply_func fn) { @@ -955,9 +1016,6 @@ static void zend_ast_export_zval(smart_str *str, zval *zv, int priority, int ind } ZEND_HASH_FOREACH_END(); smart_str_appendc(str, ']'); break; - case IS_CONSTANT: - smart_str_appendl(str, Z_STRVAL_P(zv), Z_STRLEN_P(zv)); - break; case IS_CONSTANT_AST: zend_ast_export_ex(str, Z_ASTVAL_P(zv), priority, indent); break; @@ -1037,6 +1095,14 @@ tail_call: case ZEND_AST_ZVAL: zend_ast_export_zval(str, zend_ast_get_zval(ast), priority, indent); break; + case ZEND_AST_CONSTANT: { + zend_string *name = zend_ast_get_constant_name(ast); + smart_str_appendl(str, ZSTR_VAL(name), ZSTR_LEN(name)); + break; + } + case ZEND_AST_CONSTANT_CLASS: + smart_str_appendl(str, "__CLASS__", sizeof("__CLASS__")-1); + break; case ZEND_AST_ZNODE: /* This AST kind is only used for temporary nodes during compilation */ ZEND_ASSERT(0); diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index a0aff31d70..99ad920ad6 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -32,6 +32,7 @@ enum _zend_ast_kind { /* special nodes */ ZEND_AST_ZVAL = 1 << ZEND_AST_SPECIAL_SHIFT, + ZEND_AST_CONSTANT, ZEND_AST_ZNODE, /* declaration nodes */ @@ -61,6 +62,7 @@ enum _zend_ast_kind { /* 0 child nodes */ ZEND_AST_MAGIC_CONST = 0 << ZEND_AST_NUM_CHILDREN_SHIFT, ZEND_AST_TYPE, + ZEND_AST_CONSTANT_CLASS, /* 1 child node */ ZEND_AST_VAR = 1 << ZEND_AST_NUM_CHILDREN_SHIFT, @@ -192,6 +194,8 @@ extern ZEND_API zend_ast_process_t zend_ast_process; ZEND_API zend_ast *zend_ast_create_zval_with_lineno(zval *zv, zend_ast_attr attr, uint32_t lineno); ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr); +ZEND_API zend_ast *zend_ast_create_constant(zend_string *name, zend_ast_attr attr); + ZEND_API zend_ast *zend_ast_create_ex(zend_ast_kind kind, zend_ast_attr attr, ...); ZEND_API zend_ast *zend_ast_create(zend_ast_kind kind, ...); @@ -206,9 +210,8 @@ ZEND_API zend_ast *zend_ast_list_add(zend_ast *list, zend_ast *op); ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope); ZEND_API zend_string *zend_ast_export(const char *prefix, zend_ast *ast, const char *suffix); -ZEND_API zend_ast *zend_ast_copy(zend_ast *ast); +ZEND_API zend_ast_ref *zend_ast_copy(zend_ast *ast); ZEND_API void zend_ast_destroy(zend_ast *ast); -ZEND_API void zend_ast_destroy_and_free(zend_ast *ast); typedef void (*zend_ast_apply_func)(zend_ast **ast_ptr); ZEND_API void zend_ast_apply(zend_ast *ast, zend_ast_apply_func fn); @@ -231,6 +234,12 @@ static zend_always_inline zend_string *zend_ast_get_str(zend_ast *ast) { return Z_STR_P(zv); } +static zend_always_inline zend_string *zend_ast_get_constant_name(zend_ast *ast) { + ZEND_ASSERT(ast->kind == ZEND_AST_CONSTANT); + ZEND_ASSERT(Z_TYPE(((zend_ast_zval *) ast)->val) == IS_STRING); + return Z_STR(((zend_ast_zval *) ast)->val); +} + static zend_always_inline uint32_t zend_ast_get_num_children(zend_ast *ast) { ZEND_ASSERT(!zend_ast_is_list(ast)); return ast->kind >> ZEND_AST_NUM_CHILDREN_SHIFT; diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index d0f0b7cf69..8fb7965a43 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -472,8 +472,8 @@ ZEND_FUNCTION(func_get_args) arg_count = ZEND_CALL_NUM_ARGS(ex); - array_init_size(return_value, arg_count); if (arg_count) { + array_init_size(return_value, arg_count); first_extra_arg = ex->func->op_array.num_args; zend_hash_real_init(Z_ARRVAL_P(return_value), 1); ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) { @@ -512,6 +512,8 @@ ZEND_FUNCTION(func_get_args) } } ZEND_HASH_FILL_END(); Z_ARRVAL_P(return_value)->nNumOfElements = arg_count; + } else { + ZVAL_EMPTY_ARRAY(return_value); } } /* }}} */ @@ -645,13 +647,9 @@ ZEND_FUNCTION(each) zend_hash_real_init(Z_ARRVAL_P(return_value), 0); /* add value elements */ - if (Z_ISREF_P(entry)) { - ZVAL_DUP(&tmp, Z_REFVAL_P(entry)); - entry = &tmp; - if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry); - } else { - if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry); - if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry); + ZVAL_DEREF(entry); + if (Z_REFCOUNTED_P(entry)) { + GC_ADDREF_EX(Z_COUNTED_P(entry), 2); } zend_hash_index_add_new(Z_ARRVAL_P(return_value), 1, entry); zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_VALUE), entry); @@ -659,7 +657,7 @@ ZEND_FUNCTION(each) /* add the key elements */ if (zend_hash_get_current_key(target_hash, &key, &num_key) == HASH_KEY_IS_STRING) { ZVAL_STR_COPY(&tmp, key); - if (Z_REFCOUNTED(tmp)) Z_ADDREF(tmp); + Z_TRY_ADDREF(tmp); } else { ZVAL_LONG(&tmp, num_key); } @@ -688,9 +686,9 @@ ZEND_FUNCTION(error_reporting) zend_ini_entry *p = EG(error_reporting_ini_entry); if (!p) { - p = zend_hash_find_ptr(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING)); - if (p) { - EG(error_reporting_ini_entry) = p; + zval *zv = zend_hash_find_ex(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING), 1); + if (zv) { + p = EG(error_reporting_ini_entry) = (zend_ini_entry*)Z_PTR_P(zv); } else { break; } @@ -727,13 +725,13 @@ static int validate_constant_array(HashTable *ht) /* {{{ */ int ret = 1; zval *val; - ht->u.v.nApplyCount++; + GC_PROTECT_RECURSION(ht); ZEND_HASH_FOREACH_VAL_IND(ht, val) { ZVAL_DEREF(val); if (Z_REFCOUNTED_P(val)) { if (Z_TYPE_P(val) == IS_ARRAY) { if (Z_REFCOUNTED_P(val)) { - if (Z_ARRVAL_P(val)->u.v.nApplyCount > 0) { + if (Z_IS_RECURSIVE_P(val)) { zend_error(E_WARNING, "Constants cannot be recursive arrays"); ret = 0; break; @@ -749,7 +747,7 @@ static int validate_constant_array(HashTable *ht) /* {{{ */ } } } ZEND_HASH_FOREACH_END(); - ht->u.v.nApplyCount--; + GC_UNPROTECT_RECURSION(ht); return ret; } /* }}} */ @@ -773,8 +771,8 @@ static void copy_constant_array(zval *dst, zval *src) /* {{{ */ if (Z_REFCOUNTED_P(val)) { copy_constant_array(new_val, val); } - } else if (Z_REFCOUNTED_P(val)) { - Z_ADDREF_P(val); + } else { + Z_TRY_ADDREF_P(val); } } ZEND_HASH_FOREACH_END(); } @@ -1062,16 +1060,12 @@ static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, int st /* copy: enforce read only access */ ZVAL_DEREF(prop); - if (UNEXPECTED(Z_COPYABLE_P(prop))) { - ZVAL_DUP(&prop_copy, prop); - prop = &prop_copy; - } else { - Z_TRY_ADDREF_P(prop); - } + ZVAL_COPY_OR_DUP(&prop_copy, prop); + prop = &prop_copy; /* this is necessary to make it able to work with default array * properties, returned to user */ - if (Z_OPT_CONSTANT_P(prop)) { + if (Z_OPT_TYPE_P(prop) == IS_CONSTANT_AST) { if (UNEXPECTED(zval_update_constant_ex(prop, NULL) != SUCCESS)) { return; } @@ -1137,7 +1131,7 @@ ZEND_FUNCTION(get_object_vars) zobj = Z_OBJ_P(obj); - if (!zobj->ce->default_properties_count && properties == zobj->properties && !ZEND_HASH_GET_APPLY_COUNT(properties)) { + if (!zobj->ce->default_properties_count && properties == zobj->properties && !GC_IS_RECURSIVE(properties)) { /* fast copy */ if (EXPECTED(zobj->handlers == &std_object_handlers)) { RETURN_ARR(zend_proptable_to_symtable(properties, 0)); @@ -1527,7 +1521,7 @@ ZEND_FUNCTION(class_alias) if (ce) { if (ce->type == ZEND_USER_CLASS) { - if (zend_register_class_alias_ex(alias_name, alias_name_len, ce) == SUCCESS) { + if (zend_register_class_alias_ex(alias_name, alias_name_len, ce, 0) == SUCCESS) { RETURN_TRUE; } else { zend_error(E_WARNING, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), alias_name); @@ -2030,7 +2024,7 @@ static int add_constant_info(zval *item, void *arg) /* {{{ */ return 0; } - ZVAL_DUP(&const_val, &constant->value); + ZVAL_COPY_OR_DUP(&const_val, &constant->value); zend_hash_add_new(Z_ARRVAL_P(name_array), constant->name, &const_val); return 0; } @@ -2106,7 +2100,7 @@ ZEND_FUNCTION(get_defined_constants) add_assoc_zval(return_value, module_names[module_number], &modules[module_number]); } - ZVAL_DUP(&const_val, &val->value); + ZVAL_COPY_OR_DUP(&const_val, &val->value); zend_hash_add_new(Z_ARRVAL(modules[module_number]), val->name, &const_val); } ZEND_HASH_FOREACH_END(); @@ -2122,11 +2116,11 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) / { uint32_t num_args = ZEND_CALL_NUM_ARGS(call); - array_init_size(arg_array, num_args); if (num_args) { uint32_t i = 0; zval *p = ZEND_CALL_ARG(call, 1); + array_init_size(arg_array, num_args); zend_hash_real_init(Z_ARRVAL_P(arg_array), 1); ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(arg_array)) { if (call->func->type == ZEND_USER_FUNCTION) { @@ -2142,7 +2136,7 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) / while (i < first_extra_arg) { arg_name = call->func->op_array.vars[i]; - arg = zend_hash_find_ind(call->symbol_table, arg_name); + arg = zend_hash_find_ex_ind(call->symbol_table, arg_name, 1); if (arg) { if (Z_OPT_REFCOUNTED_P(arg)) { Z_ADDREF_P(arg); @@ -2184,6 +2178,8 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) / } } ZEND_HASH_FILL_END(); Z_ARRVAL_P(arg_array)->nNumOfElements = num_args; + } else { + ZVAL_EMPTY_ARRAY(arg_array); } } /* }}} */ diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index fa4cdfd862..63cb4192bc 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -171,7 +171,7 @@ ZEND_METHOD(Closure, call) if (fci_cache.function_handler->common.fn_flags & ZEND_ACC_GENERATOR) { /* copied upon generator creation */ - --GC_REFCOUNT(&closure->std); + GC_DELREF(&closure->std); } else if (ZEND_USER_CODE(my_function.type) && closure->func.common.scope != Z_OBJCE_P(newthis)) { efree(my_function.op_array.run_time_cache); } @@ -198,7 +198,8 @@ ZEND_METHOD(Closure, bind) } else if (Z_TYPE_P(scope_arg) == IS_NULL) { ce = NULL; } else { - zend_string *class_name = zval_get_string(scope_arg); + zend_string *tmp_class_name; + zend_string *class_name = zval_get_tmp_string(scope_arg, &tmp_class_name); if (zend_string_equals_literal(class_name, "static")) { ce = closure->func.common.scope; } else if ((ce = zend_lookup_class_ex(class_name, NULL, 1)) == NULL) { @@ -206,7 +207,7 @@ ZEND_METHOD(Closure, bind) zend_string_release(class_name); RETURN_NULL(); } - zend_string_release(class_name); + zend_tmp_string_release(tmp_class_name); } } else { /* scope argument not given; do not change the scope by default */ ce = closure->func.common.scope; @@ -251,8 +252,12 @@ static ZEND_NAMED_FUNCTION(zend_closure_call_magic) /* {{{ */ { fci.params = params; fci.param_count = 2; ZVAL_STR(&fci.params[0], EX(func)->common.function_name); - array_init(&fci.params[1]); - zend_copy_parameters_array(ZEND_NUM_ARGS(), &fci.params[1]); + if (ZEND_NUM_ARGS()) { + array_init_size(&fci.params[1], ZEND_NUM_ARGS()); + zend_copy_parameters_array(ZEND_NUM_ARGS(), &fci.params[1]); + } else { + ZVAL_EMPTY_ARRAY(&fci.params[1]); + } fci.object = Z_OBJ(EX(This)); fcc.object = Z_OBJ(EX(This)); @@ -504,8 +509,7 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp) /* {{{ *is_temp = 1; - ALLOC_HASHTABLE(debug_info); - zend_hash_init(debug_info, 8, NULL, ZVAL_PTR_DTOR, 0); + debug_info = zend_new_array(8); if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) { HashTable *static_variables = closure->func.op_array.static_variables; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 629d695144..a032188e11 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -98,26 +98,6 @@ static void zend_destroy_property_info_internal(zval *zv) /* {{{ */ } /* }}} */ -static void zend_destroy_class_constant_internal(zval *zv) /* {{{ */ -{ - free(Z_PTR_P(zv)); -} -/* }}} */ - -static zend_string *zend_new_interned_string_safe(zend_string *str) /* {{{ */ { - zend_string *interned_str; - - zend_string_addref(str); - interned_str = zend_new_interned_string(str); - if (str != interned_str) { - return interned_str; - } else { - zend_string_release(str); - return str; - } -} -/* }}} */ - static zend_string *zend_build_runtime_definition_key(zend_string *name, unsigned char *lex_pos) /* {{{ */ { zend_string *result; @@ -382,8 +362,9 @@ ZEND_API zend_string *zend_set_compiled_filename(zend_string *new_compiled_filen return Z_STR_P(p); } - ZVAL_STR_COPY(&rv, new_compiled_filename); - zend_hash_update(&CG(filenames_table), new_compiled_filename, &rv); + new_compiled_filename = zend_new_interned_string(zend_string_copy(new_compiled_filename)); + ZVAL_STR(&rv, new_compiled_filename); + zend_hash_add_new(&CG(filenames_table), new_compiled_filename, &rv); CG(compiled_filename) = new_compiled_filename; return new_compiled_filename; @@ -420,16 +401,14 @@ static uint32_t get_temporary_variable(zend_op_array *op_array) /* {{{ */ } /* }}} */ -static int lookup_cv(zend_op_array *op_array, zend_string* name) /* {{{ */{ +static int lookup_cv(zend_op_array *op_array, zend_string *name) /* {{{ */{ int i = 0; zend_ulong hash_value = zend_string_hash_val(name); while (i < op_array->last_var) { if (ZSTR_VAL(op_array->vars[i]) == ZSTR_VAL(name) || (ZSTR_H(op_array->vars[i]) == hash_value && - ZSTR_LEN(op_array->vars[i]) == ZSTR_LEN(name) && - memcmp(ZSTR_VAL(op_array->vars[i]), ZSTR_VAL(name), ZSTR_LEN(name)) == 0)) { - zend_string_release(name); + zend_string_equal_content(op_array->vars[i], name))) { return (int)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, i); } i++; @@ -441,7 +420,7 @@ static int lookup_cv(zend_op_array *op_array, zend_string* name) /* {{{ */{ op_array->vars = erealloc(op_array->vars, CG(context).vars_size * sizeof(zend_string*)); } - op_array->vars[i] = zend_new_interned_string(name); + op_array->vars[i] = zend_string_copy(name); return (int)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, i); } /* }}} */ @@ -457,15 +436,21 @@ void zend_del_literal(zend_op_array *op_array, int n) /* {{{ */ } /* }}} */ +static inline zend_string *zval_make_interned_string(zval *zv) /* {{{ */ +{ + ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING); + Z_STR_P(zv) = zend_new_interned_string(Z_STR_P(zv)); + if (ZSTR_IS_INTERNED(Z_STR_P(zv))) { + Z_TYPE_FLAGS_P(zv) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE); + } + return Z_STR_P(zv); +} + /* Common part of zend_add_literal and zend_append_individual_literal */ static inline void zend_insert_literal(zend_op_array *op_array, zval *zv, int literal_position) /* {{{ */ { - if (Z_TYPE_P(zv) == IS_STRING || Z_TYPE_P(zv) == IS_CONSTANT) { - zend_string_hash_val(Z_STR_P(zv)); - Z_STR_P(zv) = zend_new_interned_string(Z_STR_P(zv)); - if (ZSTR_IS_INTERNED(Z_STR_P(zv))) { - Z_TYPE_FLAGS_P(zv) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE); - } + if (Z_TYPE_P(zv) == IS_STRING) { + zval_make_interned_string(zv); } ZVAL_COPY_VALUE(CT_CONSTANT_EX(op_array, literal_position), zv); Z_CACHE_SLOT(op_array->literals[literal_position]) = -1; @@ -786,7 +771,8 @@ void zend_do_free(znode *op1) /* {{{ */ } } else { while (opline >= CG(active_op_array)->opcodes) { - if (opline->opcode == ZEND_FETCH_LIST && + if ((opline->opcode == ZEND_FETCH_LIST_R || + opline->opcode == ZEND_FETCH_LIST_W) && opline->op1_type == IS_VAR && opline->op1.var == op1->u.op.var) { zend_emit_op(NULL, ZEND_FREE, op1, NULL); @@ -1061,7 +1047,7 @@ ZEND_API void function_add_ref(zend_function *function) /* {{{ */ } if (op_array->static_variables) { if (!(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) { - GC_REFCOUNT(op_array->static_variables)++; + GC_ADDREF(op_array->static_variables); } } op_array->run_time_cache = NULL; @@ -1076,25 +1062,28 @@ ZEND_API void function_add_ref(zend_function *function) /* {{{ */ ZEND_API int do_bind_function(const zend_op_array *op_array, const zend_op *opline, HashTable *function_table, zend_bool compile_time) /* {{{ */ { zend_function *function, *new_function; - zval *lcname, *rtd_key; + zval *lcname, *rtd_key, *zv; if (compile_time) { lcname = CT_CONSTANT_EX(op_array, opline->op1.constant); rtd_key = lcname + 1; } else { - lcname = RT_CONSTANT(op_array, opline->op1); + lcname = RT_CONSTANT(opline, opline->op1); rtd_key = lcname + 1; } - function = zend_hash_find_ptr(function_table, Z_STR_P(rtd_key)); + zv = zend_hash_find_ex(function_table, Z_STR_P(rtd_key), 1); + function = (zend_function*)Z_PTR_P(zv); new_function = zend_arena_alloc(&CG(arena), sizeof(zend_op_array)); memcpy(new_function, function, sizeof(zend_op_array)); if (zend_hash_add_ptr(function_table, Z_STR_P(lcname), new_function) == NULL) { int error_level = compile_time ? E_COMPILE_ERROR : E_ERROR; zend_function *old_function; - if ((old_function = zend_hash_find_ptr(function_table, Z_STR_P(lcname))) != NULL - && old_function->type == ZEND_USER_FUNCTION + zv = zend_hash_find_ex(function_table, Z_STR_P(lcname), 1); + ZEND_ASSERT(zv != NULL); + old_function = (zend_function*)Z_PTR_P(zv); + if (old_function->type == ZEND_USER_FUNCTION && old_function->op_array.last > 0) { zend_error_noreturn(error_level, "Cannot redeclare %s() (previously declared in %s:%d)", ZSTR_VAL(function->common.function_name), @@ -1117,17 +1106,18 @@ ZEND_API int do_bind_function(const zend_op_array *op_array, const zend_op *opli ZEND_API zend_class_entry *do_bind_class(const zend_op_array* op_array, const zend_op *opline, HashTable *class_table, zend_bool compile_time) /* {{{ */ { zend_class_entry *ce; - zval *lcname, *rtd_key; + zval *lcname, *rtd_key, *zv; if (compile_time) { lcname = CT_CONSTANT_EX(op_array, opline->op1.constant); rtd_key = lcname + 1; } else { - lcname = RT_CONSTANT(op_array, opline->op1); + lcname = RT_CONSTANT(opline, opline->op1); rtd_key = lcname + 1; } - ce = zend_hash_find_ptr(class_table, Z_STR_P(rtd_key)); - ZEND_ASSERT(ce); + zv = zend_hash_find_ex(class_table, Z_STR_P(rtd_key), 1); + ZEND_ASSERT(zv); + ce = (zend_class_entry*)Z_PTR_P(zv); ce->refcount++; if (zend_hash_add_ptr(class_table, Z_STR_P(lcname), ce) == NULL) { ce->refcount--; @@ -1152,19 +1142,19 @@ ZEND_API zend_class_entry *do_bind_class(const zend_op_array* op_array, const ze ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array, const zend_op *opline, HashTable *class_table, zend_class_entry *parent_ce, zend_bool compile_time) /* {{{ */ { zend_class_entry *ce; - zval *lcname, *rtd_key; + zval *lcname, *rtd_key, *zv; if (compile_time) { lcname = CT_CONSTANT_EX(op_array, opline->op1.constant); rtd_key = lcname + 1; } else { - lcname = RT_CONSTANT(op_array, opline->op1); + lcname = RT_CONSTANT(opline, opline->op1); rtd_key = lcname + 1; } - ce = zend_hash_find_ptr(class_table, Z_STR_P(rtd_key)); + zv = zend_hash_find_ex(class_table, Z_STR_P(rtd_key), 1); - if (!ce) { + if (!zv) { if (!compile_time) { /* If we're in compile time, in practice, it's quite possible * that we'll never reach this class declaration at runtime, @@ -1176,6 +1166,8 @@ ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array return NULL; } + ce = (zend_class_entry*)Z_PTR_P(zv); + if (zend_hash_exists(class_table, Z_STR_P(lcname))) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), ZSTR_VAL(ce->name)); } @@ -1304,7 +1296,8 @@ ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array) /* {{ CG(in_compilation) = 1; while (opline_num != (uint32_t)-1) { - zval *parent_name = RT_CONSTANT(op_array, op_array->opcodes[opline_num-1].op2); + const zend_op *opline = &op_array->opcodes[opline_num-1]; + zval *parent_name = RT_CONSTANT(opline, opline->op2); if ((ce = zend_lookup_class_ex(Z_STR_P(parent_name), parent_name + 1, 0)) != NULL) { do_bind_inherited_class(op_array, &op_array->opcodes[opline_num], EG(class_table), ce, 0); } @@ -1401,7 +1394,7 @@ static zend_bool zend_try_ct_eval_const(zval *zv, zend_string *name, zend_bool i ((c->flags & CONST_PERSISTENT) && !(CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION)) || (Z_TYPE(c->value) < IS_OBJECT && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) )) { - ZVAL_DUP(zv, &c->value); + ZVAL_COPY_OR_DUP(zv, &c->value); return 1; } @@ -1416,7 +1409,7 @@ static zend_bool zend_try_ct_eval_const(zval *zv, zend_string *name, zend_bool i c = zend_lookup_reserved_const(lookup_name, lookup_len); if (c) { - ZVAL_DUP(zv, &c->value); + ZVAL_COPY_OR_DUP(zv, &c->value); return 1; } } @@ -1569,7 +1562,7 @@ static zend_bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, /* Substitute case-sensitive (or lowercase) persistent class constants */ if (Z_TYPE_P(c) < IS_OBJECT) { - ZVAL_DUP(zv, c); + ZVAL_COPY_OR_DUP(zv, c); return 1; } @@ -1677,13 +1670,12 @@ int zend_register_auto_global(zend_string *name, zend_bool jit, zend_auto_global zend_auto_global auto_global; int retval; - auto_global.name = zend_new_interned_string(name); + auto_global.name = name; auto_global.auto_global_callback = auto_global_callback; auto_global.jit = jit; retval = zend_hash_add_mem(CG(auto_globals), auto_global.name, &auto_global, sizeof(zend_auto_global)) != NULL ? SUCCESS : FAILURE; - zend_string_release(name); return retval; } /* }}} */ @@ -1759,7 +1751,7 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify ce->default_properties_table = NULL; ce->default_static_members_table = NULL; zend_hash_init_ex(&ce->properties_info, 8, NULL, (persistent_hashes ? zend_destroy_property_info_internal : NULL), persistent_hashes, 0); - zend_hash_init_ex(&ce->constants_table, 8, NULL, (persistent_hashes ? zend_destroy_class_constant_internal : NULL), persistent_hashes, 0); + zend_hash_init_ex(&ce->constants_table, 8, NULL, NULL, persistent_hashes, 0); zend_hash_init_ex(&ce->function_table, 8, NULL, ZEND_FUNCTION_DTOR, persistent_hashes, 0); if (ce->type == ZEND_INTERNAL_CLASS) { @@ -1947,10 +1939,6 @@ ZEND_API size_t zend_dirname(char *path, size_t len) static void zend_adjust_for_fetch_type(zend_op *opline, uint32_t type) /* {{{ */ { zend_uchar factor = (opline->opcode == ZEND_FETCH_STATIC_PROP_R) ? 1 : 3; - - if (opline->opcode == ZEND_FETCH_THIS) { - return; - } switch (type & BP_VAR_MASK) { case BP_VAR_R: @@ -2091,7 +2079,8 @@ static void zend_check_live_ranges(zend_op *opline) /* {{{ */ opline->opcode == ZEND_ROPE_ADD || opline->opcode == ZEND_ROPE_END || opline->opcode == ZEND_END_SILENCE || - opline->opcode == ZEND_FETCH_LIST || + opline->opcode == ZEND_FETCH_LIST_R || + opline->opcode == ZEND_FETCH_LIST_W || opline->opcode == ZEND_VERIFY_RETURN_TYPE || opline->opcode == ZEND_BIND_LEXICAL) { /* these opcodes are handled separately */ @@ -2575,18 +2564,25 @@ static int zend_try_compile_cv(znode *result, zend_ast *ast) /* {{{ */ { zend_ast *name_ast = ast->child[0]; if (name_ast->kind == ZEND_AST_ZVAL) { - zend_string *name = zval_get_string(zend_ast_get_zval(name_ast)); + zval *zv = zend_ast_get_zval(name_ast); + zend_string *name; + + if (EXPECTED(Z_TYPE_P(zv) == IS_STRING)) { + name = zval_make_interned_string(zv); + } else { + name = zend_new_interned_string(zval_get_string_func(zv)); + } if (zend_is_auto_global(name)) { - zend_string_release(name); return FAILURE; } result->op_type = IS_CV; result->u.op.var = lookup_cv(CG(active_op_array), name); - /* lookup_cv may be using another zend_string instance */ - name = CG(active_op_array)->vars[EX_VAR_TO_NUM(result->u.op.var)]; + if (UNEXPECTED(Z_TYPE_P(zv) != IS_STRING)) { + zend_string_release(name); + } return SUCCESS; } @@ -2620,6 +2616,7 @@ static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint opline->extended_value = ZEND_FETCH_LOCAL; } + zend_adjust_for_fetch_type(opline, type); return opline; } /* }}} */ @@ -2637,14 +2634,10 @@ static zend_bool is_this_fetch(zend_ast *ast) /* {{{ */ static void zend_compile_simple_var(znode *result, zend_ast *ast, uint32_t type, int delayed) /* {{{ */ { - zend_op *opline; - if (is_this_fetch(ast)) { - opline = zend_emit_op(result, ZEND_FETCH_THIS, NULL, NULL); - zend_adjust_for_fetch_type(opline, type); + zend_emit_op(result, ZEND_FETCH_THIS, NULL, NULL); } else if (zend_try_compile_cv(result, ast) == FAILURE) { - zend_op *opline = zend_compile_simple_var_no_cv(result, ast, type, delayed); - zend_adjust_for_fetch_type(opline, type); + zend_compile_simple_var_no_cv(result, ast, type, delayed); } } /* }}} */ @@ -2665,18 +2658,13 @@ static void zend_separate_if_call_and_write(znode *node, zend_ast *ast, uint32_t void zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t type); void zend_compile_assign(znode *result, zend_ast *ast); -static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_node, zend_bool old_style); static inline void zend_emit_assign_znode(zend_ast *var_ast, znode *value_node) /* {{{ */ { znode dummy_node; - if (var_ast->kind == ZEND_AST_ARRAY) { - zend_compile_list_assign(&dummy_node, var_ast, value_node, var_ast->attr); - } else { - zend_ast *assign_ast = zend_ast_create(ZEND_AST_ASSIGN, var_ast, - zend_ast_create_znode(value_node)); - zend_compile_assign(&dummy_node, assign_ast); - } + zend_ast *assign_ast = zend_ast_create(ZEND_AST_ASSIGN, var_ast, + zend_ast_create_znode(value_node)); + zend_compile_assign(&dummy_node, assign_ast); zend_do_free(&dummy_node); } /* }}} */ @@ -2685,6 +2673,7 @@ static zend_op *zend_delayed_compile_dim(znode *result, zend_ast *ast, uint32_t { zend_ast *var_ast = ast->child[0]; zend_ast *dim_ast = ast->child[1]; + zend_op *opline; znode var_node, dim_node; @@ -2704,11 +2693,13 @@ static zend_op *zend_delayed_compile_dim(znode *result, zend_ast *ast, uint32_t zend_handle_numeric_op(&dim_node); } - return zend_delayed_emit_op(result, ZEND_FETCH_DIM_R, &var_node, &dim_node); + opline = zend_delayed_emit_op(result, ZEND_FETCH_DIM_R, &var_node, &dim_node); + zend_adjust_for_fetch_type(opline, type); + return opline; } /* }}} */ -static inline zend_op *zend_compile_dim_common(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ +static zend_op *zend_compile_dim(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ { uint32_t offset = zend_delayed_compile_begin(); zend_delayed_compile_dim(result, ast, type); @@ -2716,13 +2707,6 @@ static inline zend_op *zend_compile_dim_common(znode *result, zend_ast *ast, uin } /* }}} */ -void zend_compile_dim(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ -{ - zend_op *opline = zend_compile_dim_common(result, ast, type); - zend_adjust_for_fetch_type(opline, type); -} -/* }}} */ - static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ { zend_ast *obj_ast = ast->child[0]; @@ -2745,11 +2729,12 @@ static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t zend_alloc_polymorphic_cache_slot(opline->op2.constant); } + zend_adjust_for_fetch_type(opline, type); return opline; } /* }}} */ -static zend_op *zend_compile_prop_common(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ +static zend_op *zend_compile_prop(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ { uint32_t offset = zend_delayed_compile_begin(); zend_delayed_compile_prop(result, ast, type); @@ -2757,14 +2742,7 @@ static zend_op *zend_compile_prop_common(znode *result, zend_ast *ast, uint32_t } /* }}} */ -void zend_compile_prop(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ -{ - zend_op *opline = zend_compile_prop_common(result, ast, type); - zend_adjust_for_fetch_type(opline, type); -} -/* }}} */ - -zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast, uint32_t type, int delayed) /* {{{ */ +zend_op *zend_compile_static_prop(znode *result, zend_ast *ast, uint32_t type, int delayed) /* {{{ */ { zend_ast *class_ast = ast->child[0]; zend_ast *prop_ast = ast->child[1]; @@ -2793,14 +2771,8 @@ zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast, uint32_t SET_NODE(opline->op2, &class_node); } - return opline; -} -/* }}} */ - -void zend_compile_static_prop(znode *result, zend_ast *ast, uint32_t type, int delayed) /* {{{ */ -{ - zend_op *opline = zend_compile_static_prop_common(result, ast, type, delayed); zend_adjust_for_fetch_type(opline, type); + return opline; } /* }}} */ @@ -2818,6 +2790,30 @@ static void zend_verify_list_assign_target(zend_ast *var_ast, zend_bool old_styl } /* }}} */ +static inline void zend_emit_assign_ref_znode(zend_ast *var_ast, znode *value_node); + +/* Propagate refs used on leaf elements to the surrounding list() structures. */ +static zend_bool zend_propagate_list_refs(zend_ast *ast) { /* {{{ */ + zend_ast_list *list = zend_ast_get_list(ast); + zend_bool has_refs = 0; + uint32_t i; + + for (i = 0; i < list->children; ++i) { + zend_ast *elem_ast = list->child[i]; + + if (elem_ast) { + zend_ast *var_ast = elem_ast->child[0]; + if (var_ast->kind == ZEND_AST_ARRAY) { + elem_ast->attr = zend_propagate_list_refs(var_ast); + } + has_refs |= elem_ast->attr; + } + } + + return has_refs; +} +/* }}} */ + static void zend_compile_list_assign( znode *result, zend_ast *ast, znode *expr_node, zend_bool old_style) /* {{{ */ { @@ -2827,6 +2823,10 @@ static void zend_compile_list_assign( zend_bool is_keyed = list->children > 0 && list->child[0] != NULL && list->child[0]->child[1] != NULL; + if (list->children && expr_node->op_type == IS_CONST && Z_TYPE(expr_node->u.constant) == IS_STRING) { + zval_make_interned_string(&expr_node->u.constant); + } + for (i = 0; i < list->children; ++i) { zend_ast *elem_ast = list->child[i]; zend_ast *var_ast, *key_ast; @@ -2841,10 +2841,6 @@ static void zend_compile_list_assign( } } - if (elem_ast->attr) { - zend_error(E_COMPILE_ERROR, "[] and list() assignments cannot be by reference"); - } - var_ast = elem_ast->child[0]; key_ast = elem_ast->child[1]; has_elems = 1; @@ -2872,15 +2868,30 @@ static void zend_compile_list_assign( zend_verify_list_assign_target(var_ast, old_style); - zend_emit_op(&fetch_result, ZEND_FETCH_LIST, expr_node, &dim_node); - zend_emit_assign_znode(var_ast, &fetch_result); + zend_emit_op(&fetch_result, + elem_ast->attr ? ZEND_FETCH_LIST_W : ZEND_FETCH_LIST_R, expr_node, &dim_node); + + if (var_ast->kind == ZEND_AST_ARRAY) { + if (elem_ast->attr) { + zend_emit_op(&fetch_result, ZEND_MAKE_REF, &fetch_result, NULL); + } + zend_compile_list_assign(NULL, var_ast, &fetch_result, var_ast->attr); + } else if (elem_ast->attr) { + zend_emit_assign_ref_znode(var_ast, &fetch_result); + } else { + zend_emit_assign_znode(var_ast, &fetch_result); + } } if (has_elems == 0) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot use empty list"); } - *result = *expr_node; + if (result) { + *result = *expr_node; + } else { + zend_do_free(expr_node); + } } /* }}} */ @@ -2999,7 +3010,13 @@ void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */ if (zend_is_assign_to_self(var_ast, expr_ast) && !is_this_fetch(expr_ast)) { /* $a[0] = $a should evaluate the right $a first */ - zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0); + znode cv_node; + + if (zend_try_compile_cv(&cv_node, expr_ast) == FAILURE) { + zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0); + } else { + zend_emit_op(&expr_node, ZEND_QM_ASSIGN, &cv_node, NULL); + } } else { zend_compile_expr(&expr_node, expr_ast); } @@ -3020,11 +3037,32 @@ void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */ zend_emit_op_data(&expr_node); return; case ZEND_AST_ARRAY: - if (zend_list_has_assign_to_self(var_ast, expr_ast)) { - /* list($a, $b) = $a should evaluate the right $a first */ - zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0); + if (zend_propagate_list_refs(var_ast)) { + if (!zend_is_variable(expr_ast)) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot assign reference to non referencable value"); + } + + zend_compile_var(&expr_node, expr_ast, BP_VAR_W); + /* MAKE_REF is usually not necessary for CVs. However, if there are + * self-assignments, this forces the RHS to evaluate first. */ + if (expr_node.op_type != IS_CV + || zend_list_has_assign_to_self(var_ast, expr_ast)) { + zend_emit_op(&expr_node, ZEND_MAKE_REF, &expr_node, NULL); + } } else { - zend_compile_expr(&expr_node, expr_ast); + if (zend_list_has_assign_to_self(var_ast, expr_ast)) { + /* list($a, $b) = $a should evaluate the right $a first */ + znode cv_node; + + if (zend_try_compile_cv(&cv_node, expr_ast) == FAILURE) { + zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0); + } else { + zend_emit_op(&expr_node, ZEND_QM_ASSIGN, &cv_node, NULL); + } + } else { + zend_compile_expr(&expr_node, expr_ast); + } } zend_compile_list_assign(result, var_ast, &expr_node, var_ast->attr); @@ -3402,7 +3440,11 @@ int zend_compile_func_typecheck(znode *result, zend_ast_list *args, uint32_t typ zend_compile_expr(&arg_node, args->child[0]); opline = zend_emit_op_tmp(result, ZEND_TYPE_CHECK, &arg_node, NULL); - opline->extended_value = type; + if (type != _IS_BOOL) { + opline->extended_value = (1 << type); + } else { + opline->extended_value = (1 << IS_FALSE) | (1 << IS_TRUE); + } return SUCCESS; } /* }}} */ @@ -3711,9 +3753,8 @@ static int zend_compile_func_in_array(znode *result, zend_ast_list *args) /* {{{ zend_bool ok = 1; zval *val, tmp; HashTable *src = Z_ARRVAL(array.u.constant); - HashTable *dst = emalloc(sizeof(HashTable)); + HashTable *dst = zend_new_array(zend_hash_num_elements(src)); - zend_hash_init(dst, zend_hash_num_elements(src), NULL, ZVAL_PTR_DTOR, 0); ZVAL_TRUE(&tmp); if (strict) { @@ -4232,32 +4273,38 @@ static void zend_compile_static_var_common(zend_ast *var_ast, zval *value, zend_ { znode var_node; zend_op *opline; + zend_string *var_name; - zend_compile_expr(&var_node, var_ast); + if (var_ast->kind == ZEND_AST_ZVAL) { + var_name = zval_make_interned_string(zend_ast_get_zval(var_ast)); + zend_compile_expr(&var_node, var_ast); + } else { + zend_compile_expr(&var_node, var_ast); + var_name = zval_make_interned_string(&var_node.u.constant); + } if (!CG(active_op_array)->static_variables) { if (CG(active_op_array)->scope) { CG(active_op_array)->scope->ce_flags |= ZEND_HAS_STATIC_IN_METHODS; } - ALLOC_HASHTABLE(CG(active_op_array)->static_variables); - zend_hash_init(CG(active_op_array)->static_variables, 8, NULL, ZVAL_PTR_DTOR, 0); + CG(active_op_array)->static_variables = zend_new_array(8); } if (GC_REFCOUNT(CG(active_op_array)->static_variables) > 1) { if (!(GC_FLAGS(CG(active_op_array)->static_variables) & IS_ARRAY_IMMUTABLE)) { - GC_REFCOUNT(CG(active_op_array)->static_variables)--; + GC_DELREF(CG(active_op_array)->static_variables); } CG(active_op_array)->static_variables = zend_array_dup(CG(active_op_array)->static_variables); } - zend_hash_update(CG(active_op_array)->static_variables, Z_STR(var_node.u.constant), value); + zend_hash_update(CG(active_op_array)->static_variables, var_name, value); - if (zend_string_equals_literal(Z_STR(var_node.u.constant), "this")) { + if (zend_string_equals_literal(var_name, "this")) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot use $this as static variable"); } opline = zend_emit_op(NULL, ZEND_BIND_STATIC, NULL, &var_node); opline->op1_type = IS_CV; - opline->op1.var = lookup_cv(CG(active_op_array), zend_string_copy(Z_STR(var_node.u.constant))); + opline->op1.var = lookup_cv(CG(active_op_array), var_name); opline->extended_value = by_ref; } /* }}} */ @@ -4298,15 +4345,15 @@ void zend_compile_unset(zend_ast *ast) /* {{{ */ } return; case ZEND_AST_DIM: - opline = zend_compile_dim_common(NULL, var_ast, BP_VAR_UNSET); + opline = zend_compile_dim(NULL, var_ast, BP_VAR_UNSET); opline->opcode = ZEND_UNSET_DIM; return; case ZEND_AST_PROP: - opline = zend_compile_prop_common(NULL, var_ast, BP_VAR_UNSET); + opline = zend_compile_prop(NULL, var_ast, BP_VAR_UNSET); opline->opcode = ZEND_UNSET_OBJ; return; case ZEND_AST_STATIC_PROP: - opline = zend_compile_static_prop_common(NULL, var_ast, BP_VAR_UNSET, 0); + opline = zend_compile_static_prop(NULL, var_ast, BP_VAR_UNSET, 0); opline->opcode = ZEND_UNSET_STATIC_PROP; return; EMPTY_SWITCH_DEFAULT_CASE() @@ -4755,6 +4802,10 @@ void zend_compile_foreach(zend_ast *ast) /* {{{ */ value_ast = value_ast->child[0]; } + if (value_ast->kind == ZEND_AST_ARRAY && zend_propagate_list_refs(value_ast)) { + by_ref = 1; + } + if (by_ref && is_variable) { zend_compile_var(&expr_node, expr_ast, BP_VAR_W); } else { @@ -4776,13 +4827,15 @@ void zend_compile_foreach(zend_ast *ast) /* {{{ */ if (is_this_fetch(value_ast)) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); } else if (value_ast->kind == ZEND_AST_VAR && - zend_try_compile_cv(&value_node, value_ast) == SUCCESS) { + zend_try_compile_cv(&value_node, value_ast) == SUCCESS) { SET_NODE(opline->op2, &value_node); } else { opline->op2_type = IS_VAR; opline->op2.var = get_temporary_variable(CG(active_op_array)); GET_NODE(&value_node, opline->op2); - if (by_ref) { + if (value_ast->kind == ZEND_AST_ARRAY) { + zend_compile_list_assign(NULL, value_ast, &value_node, value_ast->attr); + } else if (by_ref) { zend_emit_assign_ref_znode(value_ast, &value_node); } else { zend_emit_assign_znode(value_ast, &value_node); @@ -5097,7 +5150,7 @@ void zend_compile_try(zend_ast *ast) /* {{{ */ zend_ast_list *classes = zend_ast_get_list(catch_ast->child[0]); zend_ast *var_ast = catch_ast->child[1]; zend_ast *stmt_ast = catch_ast->child[2]; - zval *var_name = zend_ast_get_zval(var_ast); + zend_string *var_name = zval_make_interned_string(zend_ast_get_zval(var_ast)); zend_bool is_last_catch = (i + 1 == catches->children); uint32_t *jmp_multicatch = safe_emalloc(sizeof(uint32_t), classes->children - 1, 0); @@ -5125,12 +5178,12 @@ void zend_compile_try(zend_ast *ast) /* {{{ */ opline->op1.constant = zend_add_class_name_literal(CG(active_op_array), zend_resolve_class_name_ast(class_ast)); - if (zend_string_equals_literal(Z_STR_P(var_name), "this")) { + if (zend_string_equals_literal(var_name, "this")) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); } opline->op2_type = IS_CV; - opline->op2.var = lookup_cv(CG(active_op_array), zend_string_copy(Z_STR_P(var_name))); + opline->op2.var = lookup_cv(CG(active_op_array), var_name); opline->result.num = is_last_catch && is_last_class; @@ -5453,7 +5506,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */ zend_ast *type_ast = param_ast->child[0]; zend_ast *var_ast = param_ast->child[1]; zend_ast *default_ast = param_ast->child[2]; - zend_string *name = zend_ast_get_str(var_ast); + zend_string *name = zval_make_interned_string(zend_ast_get_zval(var_ast)); zend_bool is_ref = (param_ast->attr & ZEND_PARAM_REF) != 0; zend_bool is_variadic = (param_ast->attr & ZEND_PARAM_VARIADIC) != 0; @@ -5468,7 +5521,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */ } var_node.op_type = IS_CV; - var_node.u.op.var = lookup_cv(CG(active_op_array), zend_string_copy(name)); + var_node.u.op.var = lookup_cv(CG(active_op_array), name); if (EX_VAR_TO_NUM(var_node.u.op.var) != i) { zend_error_noreturn(E_COMPILE_ERROR, "Redefinition of parameter $%s", @@ -5519,8 +5572,9 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */ zend_bool allow_null; zend_bool has_null_default = default_ast && (Z_TYPE(default_node.u.constant) == IS_NULL - || (Z_TYPE(default_node.u.constant) == IS_CONSTANT - && strcasecmp(Z_STRVAL(default_node.u.constant), "NULL") == 0)); + || (Z_TYPE(default_node.u.constant) == IS_CONSTANT_AST + && Z_ASTVAL(default_node.u.constant)->kind == ZEND_AST_CONSTANT + && strcasecmp(ZSTR_VAL(zend_ast_get_constant_name(Z_ASTVAL(default_node.u.constant))), "NULL") == 0)); zend_bool is_explicitly_nullable = (type_ast->attr & ZEND_TYPE_NULLABLE) == ZEND_TYPE_NULLABLE; op_array->fn_flags |= ZEND_ACC_HAS_TYPE_HINTS; @@ -5537,19 +5591,19 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */ if (ZEND_TYPE_CODE(arg_info->type) == IS_ARRAY) { if (default_ast && !has_null_default && Z_TYPE(default_node.u.constant) != IS_ARRAY - && !Z_CONSTANT(default_node.u.constant) + && Z_TYPE(default_node.u.constant) != IS_CONSTANT_AST ) { zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters " "with array type can only be an array or NULL"); } } else if (ZEND_TYPE_CODE(arg_info->type) == IS_CALLABLE && default_ast) { - if (!has_null_default && !Z_CONSTANT(default_node.u.constant)) { + if (!has_null_default && Z_TYPE(default_node.u.constant) != IS_CONSTANT_AST) { zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters " "with callable type can only be NULL"); } } } else { - if (default_ast && !has_null_default && !Z_CONSTANT(default_node.u.constant)) { + if (default_ast && !has_null_default && Z_TYPE(default_node.u.constant) != IS_CONSTANT_AST) { if (ZEND_TYPE_IS_CLASS(arg_info->type)) { zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters " "with a class type can only be NULL"); @@ -5627,7 +5681,7 @@ static void zend_compile_closure_binding(znode *closure, zend_ast *uses_ast) /* for (i = 0; i < list->children; ++i) { zend_ast *var_name_ast = list->child[i]; - zend_string *var_name = zend_ast_get_str(var_name_ast); + zend_string *var_name = zval_make_interned_string(zend_ast_get_zval(var_name_ast)); zend_bool by_ref = var_name_ast->attr; zend_op *opline; @@ -5641,7 +5695,7 @@ static void zend_compile_closure_binding(znode *closure, zend_ast *uses_ast) /* opline = zend_emit_op(NULL, ZEND_BIND_LEXICAL, closure, NULL); opline->op2_type = IS_CV; - opline->op2.var = lookup_cv(CG(active_op_array), zend_string_copy(var_name)); + opline->op2.var = lookup_cv(CG(active_op_array), var_name); opline->extended_value = by_ref; } } @@ -6005,7 +6059,7 @@ void zend_compile_prop_decl(zend_ast *ast) /* {{{ */ zend_ast *name_ast = prop_ast->child[0]; zend_ast *value_ast = prop_ast->child[1]; zend_ast *doc_comment_ast = prop_ast->child[2]; - zend_string *name = zend_ast_get_str(name_ast); + zend_string *name = zval_make_interned_string(zend_ast_get_zval(name_ast)); zend_string *doc_comment = NULL; zval value_zv; @@ -6031,7 +6085,6 @@ void zend_compile_prop_decl(zend_ast *ast) /* {{{ */ ZVAL_NULL(&value_zv); } - name = zend_new_interned_string_safe(name); zend_declare_property_ex(ce, name, &value_zv, flags, doc_comment); } } @@ -6053,7 +6106,7 @@ void zend_compile_class_const_decl(zend_ast *ast) /* {{{ */ zend_ast *name_ast = const_ast->child[0]; zend_ast *value_ast = const_ast->child[1]; zend_ast *doc_comment_ast = const_ast->child[2]; - zend_string *name = zend_ast_get_str(name_ast); + zend_string *name = zval_make_interned_string(zend_ast_get_zval(name_ast)); zend_string *doc_comment = doc_comment_ast ? zend_string_copy(zend_ast_get_str(doc_comment_ast)) : NULL; zval value_zv; @@ -6068,8 +6121,6 @@ void zend_compile_class_const_decl(zend_ast *ast) /* {{{ */ } zend_const_expr_to_zval(&value_zv, value_ast); - - name = zend_new_interned_string_safe(name); zend_declare_class_constant_ex(ce, name, &value_zv, ast->attr, doc_comment); } } @@ -6937,6 +6988,11 @@ static zend_bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */ return 0; } + if (!list->children) { + ZVAL_EMPTY_ARRAY(result); + return 1; + } + array_init_size(result, list->children); for (i = 0; i < list->children; ++i) { zend_ast *elem_ast = list->child[i]; @@ -6944,7 +7000,7 @@ static zend_bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */ zend_ast *key_ast = elem_ast->child[1]; zval *value = zend_ast_get_zval(value_ast); - if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value); + Z_TRY_ADDREF_P(value); if (key_ast) { zval *key = zend_ast_get_zval(key_ast); @@ -7180,7 +7236,7 @@ void zend_compile_post_incdec(znode *result, zend_ast *ast) /* {{{ */ zend_ensure_writable_variable(var_ast); if (var_ast->kind == ZEND_AST_PROP) { - zend_op *opline = zend_compile_prop_common(NULL, var_ast, BP_VAR_RW); + zend_op *opline = zend_compile_prop(NULL, var_ast, BP_VAR_RW); opline->opcode = ast->kind == ZEND_AST_POST_INC ? ZEND_POST_INC_OBJ : ZEND_POST_DEC_OBJ; zend_make_tmp_result(result, opline); } else { @@ -7200,7 +7256,7 @@ void zend_compile_pre_incdec(znode *result, zend_ast *ast) /* {{{ */ zend_ensure_writable_variable(var_ast); if (var_ast->kind == ZEND_AST_PROP) { - zend_op *opline = zend_compile_prop_common(result, var_ast, BP_VAR_RW); + zend_op *opline = zend_compile_prop(result, var_ast, BP_VAR_RW); opline->opcode = ast->kind == ZEND_AST_PRE_INC ? ZEND_PRE_INC_OBJ : ZEND_PRE_DEC_OBJ; } else { znode var_node; @@ -7476,15 +7532,15 @@ void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */ } break; case ZEND_AST_DIM: - opline = zend_compile_dim_common(result, var_ast, BP_VAR_IS); + opline = zend_compile_dim(result, var_ast, BP_VAR_IS); opline->opcode = ZEND_ISSET_ISEMPTY_DIM_OBJ; break; case ZEND_AST_PROP: - opline = zend_compile_prop_common(result, var_ast, BP_VAR_IS); + opline = zend_compile_prop(result, var_ast, BP_VAR_IS); opline->opcode = ZEND_ISSET_ISEMPTY_PROP_OBJ; break; case ZEND_AST_STATIC_PROP: - opline = zend_compile_static_prop_common(result, var_ast, BP_VAR_IS, 0); + opline = zend_compile_static_prop(result, var_ast, BP_VAR_IS, 0); opline->opcode = ZEND_ISSET_ISEMPTY_STATIC_PROP; break; EMPTY_SWITCH_DEFAULT_CASE() @@ -7917,6 +7973,7 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */ zend_ast *const_ast = ast->child[1]; zend_string *class_name; zend_string *const_name = zend_ast_get_str(const_ast); + zend_string *name; zval result; int fetch_type; @@ -7944,16 +8001,13 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */ zend_string_addref(class_name); } - Z_STR(result) = zend_concat3( + name = zend_concat3( ZSTR_VAL(class_name), ZSTR_LEN(class_name), "::", 2, ZSTR_VAL(const_name), ZSTR_LEN(const_name)); - Z_TYPE_INFO(result) = IS_CONSTANT_EX; - Z_CONST_FLAGS(result) = fetch_type; - zend_ast_destroy(ast); zend_string_release(class_name); - *ast_ptr = zend_ast_create_zval(&result); + *ast_ptr = zend_ast_create_constant(name, fetch_type); } /* }}} */ @@ -7963,25 +8017,21 @@ void zend_compile_const_expr_const(zend_ast **ast_ptr) /* {{{ */ zend_ast *name_ast = ast->child[0]; zend_string *orig_name = zend_ast_get_str(name_ast); zend_bool is_fully_qualified; + zval result; + zend_string *resolved_name; - zval result, resolved_name; - ZVAL_STR(&resolved_name, zend_resolve_const_name( - orig_name, name_ast->attr, &is_fully_qualified)); + resolved_name = zend_resolve_const_name( + orig_name, name_ast->attr, &is_fully_qualified); - if (zend_try_ct_eval_const(&result, Z_STR(resolved_name), is_fully_qualified)) { - zend_string_release(Z_STR(resolved_name)); + if (zend_try_ct_eval_const(&result, resolved_name, is_fully_qualified)) { + zend_string_release(resolved_name); zend_ast_destroy(ast); *ast_ptr = zend_ast_create_zval(&result); return; } - Z_TYPE_INFO(resolved_name) = IS_CONSTANT_EX; - if (!is_fully_qualified) { - Z_CONST_FLAGS(resolved_name) = IS_CONSTANT_UNQUALIFIED; - } - zend_ast_destroy(ast); - *ast_ptr = zend_ast_create_zval(&resolved_name); + *ast_ptr = zend_ast_create_constant(resolved_name, !is_fully_qualified ? IS_CONSTANT_UNQUALIFIED : 0); } /* }}} */ @@ -7994,14 +8044,8 @@ void zend_compile_const_expr_magic_const(zend_ast **ast_ptr) /* {{{ */ CG(active_class_entry) && (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != 0); - { - zval const_zv; - Z_STR(const_zv) = zend_string_init("__CLASS__", sizeof("__CLASS__")-1, 0); - Z_TYPE_INFO(const_zv) = IS_CONSTANT_EX | (IS_CONSTANT_CLASS << Z_CONST_FLAGS_SHIFT); - - zend_ast_destroy(ast); - *ast_ptr = zend_ast_create_zval(&const_zv); - } + zend_ast_destroy(ast); + *ast_ptr = zend_ast_create_ex(ZEND_AST_CONSTANT_CLASS, 0); } /* }}} */ @@ -8041,7 +8085,7 @@ void zend_const_expr_to_zval(zval *result, zend_ast *ast) /* {{{ */ if (ast->kind == ZEND_AST_ZVAL) { ZVAL_COPY_VALUE(result, zend_ast_get_zval(ast)); } else { - ZVAL_NEW_AST(result, zend_ast_copy(ast)); + ZVAL_AST(result, zend_ast_copy(ast)); /* destroy the ast here, it might have been replaced */ zend_ast_destroy(ast); } @@ -8361,18 +8405,15 @@ void zend_compile_var(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ void zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ { - zend_op *opline; switch (ast->kind) { case ZEND_AST_VAR: zend_compile_simple_var(result, ast, type, 1); return; case ZEND_AST_DIM: - opline = zend_delayed_compile_dim(result, ast, type); - zend_adjust_for_fetch_type(opline, type); + zend_delayed_compile_dim(result, ast, type); return; case ZEND_AST_PROP: - opline = zend_delayed_compile_prop(result, ast, type); - zend_adjust_for_fetch_type(opline, type); + zend_delayed_compile_prop(result, ast, type); return; case ZEND_AST_STATIC_PROP: zend_compile_static_prop(result, ast, type, 1); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 55526d6739..868f3ab986 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -59,12 +59,10 @@ typedef struct _zend_op zend_op; #if SIZEOF_SIZE_T == 4 # define ZEND_USE_ABS_JMP_ADDR 1 # define ZEND_USE_ABS_CONST_ADDR 1 -# define ZEND_EX_USE_LITERALS 0 # define ZEND_EX_USE_RUN_TIME_CACHE 1 #else # define ZEND_USE_ABS_JMP_ADDR 0 # define ZEND_USE_ABS_CONST_ADDR 0 -# define ZEND_EX_USE_LITERALS 1 # define ZEND_EX_USE_RUN_TIME_CACHE 1 #endif @@ -410,7 +408,7 @@ struct _zend_op_array { #define ZEND_RETURN_REFERENCE 1 /* zend_internal_function_handler */ -typedef void (*zif_handler)(INTERNAL_FUNCTION_PARAMETERS); +typedef void (ZEND_FASTCALL *zif_handler)(INTERNAL_FUNCTION_PARAMETERS); typedef struct _zend_internal_function { /* Common elements */ @@ -470,9 +468,6 @@ struct _zend_execute_data { #if ZEND_EX_USE_RUN_TIME_CACHE void **run_time_cache; /* cache op_array->run_time_cache */ #endif -#if ZEND_EX_USE_LITERALS - zval *literals; /* cache op_array->literals */ -#endif }; #define ZEND_CALL_FUNCTION (0 << 0) @@ -616,64 +611,38 @@ struct _zend_execute_data { #if ZEND_USE_ABS_CONST_ADDR /* run-time constant */ -# define RT_CONSTANT_EX(base, node) \ +# define RT_CONSTANT(opline, node) \ (node).zv /* convert constant from compile-time to run-time */ -# define ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, node) do { \ +# define ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline, node) do { \ (node).zv = CT_CONSTANT_EX(op_array, (node).constant); \ } while (0) -/* convert constant back from run-time to compile-time */ -# define ZEND_PASS_TWO_UNDO_CONSTANT(op_array, node) do { \ - (node).constant = (node).zv - (op_array)->literals; \ - } while (0) - #else +/* At run-time, constants are allocated together with op_array->opcodes + * and addressed relatively to current opline. + */ + /* run-time constant */ -# define RT_CONSTANT_EX(base, node) \ - ((zval*)(((char*)(base)) + (node).constant)) +# define RT_CONSTANT(opline, node) \ + ((zval*)(((char*)(opline)) + (int32_t)(node).constant)) /* convert constant from compile-time to run-time */ -# define ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, node) do { \ - (node).constant *= sizeof(zval); \ - } while (0) - -/* convert constant back from run-time to compile-time (do nothing) */ -# define ZEND_PASS_TWO_UNDO_CONSTANT(op_array, node) do { \ - (node).constant /= sizeof(zval); \ +# define ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline, node) do { \ + (node).constant = \ + (((char*)CT_CONSTANT_EX(op_array, (node).constant)) - \ + ((char*)opline)); \ } while (0) #endif -#if ZEND_EX_USE_LITERALS - -# define EX_LITERALS() \ - EX(literals) - -# define EX_LOAD_LITERALS(op_array) do { \ - EX(literals) = (op_array)->literals; \ - } while (0) - -#else - -# define EX_LITERALS() \ - EX(func)->op_array.literals - -# define EX_LOAD_LITERALS(op_array) do { \ +/* convert constant back from run-time to compile-time */ +#define ZEND_PASS_TWO_UNDO_CONSTANT(op_array, opline, node) do { \ + (node).constant = RT_CONSTANT(opline, node) - (op_array)->literals; \ } while (0) -#endif - -/* run-time constant */ -#define RT_CONSTANT(op_array, node) \ - RT_CONSTANT_EX((op_array)->literals, node) - -/* constant in currently executed function */ -#define EX_CONSTANT(node) \ - RT_CONSTANT_EX(EX_LITERALS(), node) - #if ZEND_EX_USE_RUN_TIME_CACHE # define EX_RUN_TIME_CACHE() \ @@ -917,6 +886,10 @@ void zend_assert_valid_class_name(const zend_string *const_name); #define ZEND_DIM_IS 1 +#define IS_CONSTANT_UNQUALIFIED 0x010 +#define IS_CONSTANT_CLASS 0x080 /* __CLASS__ in trait */ +#define IS_CONSTANT_IN_NAMESPACE 0x100 + static zend_always_inline int zend_check_arg_send_type(const zend_function *zf, uint32_t arg_num, uint32_t mask) { arg_num--; diff --git a/Zend/zend_config.w32.h b/Zend/zend_config.w32.h index 2ba42cdc9d..ddebdeaed8 100644 --- a/Zend/zend_config.w32.h +++ b/Zend/zend_config.w32.h @@ -58,19 +58,14 @@ typedef unsigned int uint; #define zend_sprintf sprintf +#ifndef __cplusplus /* This will cause the compilation process to be MUCH longer, but will generate * a much quicker PHP binary */ #ifdef ZEND_WIN32_FORCE_INLINE -/* _ALLOW_KEYWORD_MACROS is only relevant for C++ */ -# ifndef _ALLOW_KEYWORD_MACROS -# define _ALLOW_KEYWORD_MACROS -# endif # undef inline # define inline __forceinline -#elif !defined(ZEND_WIN32_KEEP_INLINE) -# undef inline -# define inline +#endif #endif #ifdef LIBZEND_EXPORTS diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index f5a71ac6cc..42bccda28f 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -44,21 +44,19 @@ void free_zend_constant(zval *zv) } +#ifdef ZTS static void copy_zend_constant(zval *zv) { zend_constant *c = Z_PTR_P(zv); - Z_PTR_P(zv) = pemalloc(sizeof(zend_constant), c->flags & CONST_PERSISTENT); + ZEND_ASSERT(c->flags & CONST_PERSISTENT); + Z_PTR_P(zv) = pemalloc(sizeof(zend_constant), 1); memcpy(Z_PTR_P(zv), c, sizeof(zend_constant)); c = Z_PTR_P(zv); c->name = zend_string_copy(c->name); - if (!(c->flags & CONST_PERSISTENT)) { - zval_copy_ctor(&c->value); - } else { - if (Z_TYPE(c->value) == IS_STRING) { - Z_STR(c->value) = zend_string_dup(Z_STR(c->value), 1); - } + if (Z_TYPE(c->value) == IS_STRING) { + Z_STR(c->value) = zend_string_dup(Z_STR(c->value), 1); } } @@ -67,6 +65,7 @@ void zend_copy_constants(HashTable *target, HashTable *source) { zend_hash_copy(target, source, copy_zend_constant); } +#endif static int clean_module_constant(zval *el, void *arg) @@ -144,7 +143,7 @@ ZEND_API void zend_register_null_constant(const char *name, size_t name_len, int ZVAL_NULL(&c.value); c.flags = flags; - c.name = zend_string_init(name, name_len, flags & CONST_PERSISTENT); + c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); c.module_number = module_number; zend_register_constant(&c); } @@ -155,7 +154,7 @@ ZEND_API void zend_register_bool_constant(const char *name, size_t name_len, zen ZVAL_BOOL(&c.value, bval); c.flags = flags; - c.name = zend_string_init(name, name_len, flags & CONST_PERSISTENT); + c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); c.module_number = module_number; zend_register_constant(&c); } @@ -166,7 +165,7 @@ ZEND_API void zend_register_long_constant(const char *name, size_t name_len, zen ZVAL_LONG(&c.value, lval); c.flags = flags; - c.name = zend_string_init(name, name_len, flags & CONST_PERSISTENT); + c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); c.module_number = module_number; zend_register_constant(&c); } @@ -178,7 +177,7 @@ ZEND_API void zend_register_double_constant(const char *name, size_t name_len, d ZVAL_DOUBLE(&c.value, dval); c.flags = flags; - c.name = zend_string_init(name, name_len, flags & CONST_PERSISTENT); + c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); c.module_number = module_number; zend_register_constant(&c); } @@ -188,9 +187,9 @@ ZEND_API void zend_register_stringl_constant(const char *name, size_t name_len, { zend_constant c; - ZVAL_NEW_STR(&c.value, zend_string_init(strval, strlen, flags & CONST_PERSISTENT)); + ZVAL_STR(&c.value, zend_string_init_interned(strval, strlen, flags & CONST_PERSISTENT)); c.flags = flags; - c.name = zend_string_init(name, name_len, flags & CONST_PERSISTENT); + c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); c.module_number = module_number; zend_register_constant(&c); } @@ -204,7 +203,7 @@ ZEND_API void zend_register_string_constant(const char *name, size_t name_len, c static zend_constant *zend_get_special_constant(const char *name, size_t name_len) { zend_constant *c; - static char haltoff[] = "__COMPILER_HALT_OFFSET__"; + static const char haltoff[] = "__COMPILER_HALT_OFFSET__"; if (!EG(current_execute_data)) { return NULL; @@ -348,7 +347,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, } } - if (ret_constant && Z_CONSTANT_P(ret_constant)) { + if (ret_constant && Z_TYPE_P(ret_constant) == IS_CONSTANT_AST) { if (Z_TYPE_P(ret_constant) == IS_CONSTANT_AST) { if (IS_CONSTANT_VISITED(ret_constant)) { zend_throw_error(NULL, "Cannot declare self-referencing constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name)); @@ -417,26 +416,30 @@ failure: ZEND_API zend_constant* ZEND_FASTCALL zend_quick_get_constant(const zval *key, uint32_t flags) { - zend_constant *c; + zval *zv; + zend_constant *c = NULL; - if ((c = zend_hash_find_ptr(EG(zend_constants), Z_STR_P(key))) == NULL) { + zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1); + if (zv) { + c = (zend_constant*)Z_PTR_P(zv); + } else { key++; - if ((c = zend_hash_find_ptr(EG(zend_constants), Z_STR_P(key))) == NULL || - (c->flags & CONST_CS) != 0) { + zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1); + if (zv && (((zend_constant*)Z_PTR_P(zv))->flags & CONST_CS) == 0) { + c = (zend_constant*)Z_PTR_P(zv); + } else { if ((flags & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) { key++; - if ((c = zend_hash_find_ptr(EG(zend_constants), Z_STR_P(key))) == NULL) { + zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1); + if (zv) { + c = (zend_constant*)Z_PTR_P(zv); + } else { key++; - if ((c = zend_hash_find_ptr(EG(zend_constants), Z_STR_P(key))) == NULL || - (c->flags & CONST_CS) != 0) { - - key--; - c = NULL; + zv = zend_hash_find_ex(EG(zend_constants), Z_STR_P(key), 1); + if (zv && (((zend_constant*)Z_PTR_P(zv))->flags & CONST_CS) == 0) { + c = (zend_constant*)Z_PTR_P(zv); } } - } else { - key--; - c = NULL; } } } @@ -466,13 +469,8 @@ ZEND_API int zend_register_constant(zend_constant *c) printf("Registering constant for module %d\n", c->module_number); #endif - if (c->module_number != PHP_USER_CONSTANT) { - c->name = zend_new_interned_string(c->name); - } - if (!(c->flags & CONST_CS)) { - lowercase_name = zend_string_alloc(ZSTR_LEN(c->name), c->flags & CONST_PERSISTENT); - zend_str_tolower_copy(ZSTR_VAL(lowercase_name), ZSTR_VAL(c->name), ZSTR_LEN(c->name)); + lowercase_name = zend_string_tolower_ex(c->name, c->flags & CONST_PERSISTENT); lowercase_name = zend_new_interned_string(lowercase_name); name = lowercase_name; } else { @@ -488,8 +486,7 @@ ZEND_API int zend_register_constant(zend_constant *c) } /* Check if the user is trying to define the internal pseudo constant name __COMPILER_HALT_OFFSET__ */ - if ((ZSTR_LEN(c->name) == sizeof("__COMPILER_HALT_OFFSET__")-1 - && !memcmp(ZSTR_VAL(name), "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1)) + if (zend_string_equals_literal(name, "__COMPILER_HALT_OFFSET__") || zend_hash_add_constant(EG(zend_constants), name, c) == NULL) { /* The internal __COMPILER_HALT_OFFSET__ is prefixed by NULL byte */ diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h index 3bbe9a81da..fae72e5bf9 100644 --- a/Zend/zend_constants.h +++ b/Zend/zend_constants.h @@ -75,7 +75,9 @@ ZEND_API void zend_register_double_constant(const char *name, size_t name_len, d ZEND_API void zend_register_string_constant(const char *name, size_t name_len, char *strval, int flags, int module_number); ZEND_API void zend_register_stringl_constant(const char *name, size_t name_len, char *strval, size_t strlen, int flags, int module_number); ZEND_API int zend_register_constant(zend_constant *c); +#ifdef ZTS void zend_copy_constants(HashTable *target, HashTable *sourc); +#endif ZEND_API zend_constant* ZEND_FASTCALL zend_quick_get_constant(const zval *key, uint32_t flags); END_EXTERN_C() diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 4bf2b746cb..5049fe966a 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -100,7 +100,7 @@ void zend_exception_set_previous(zend_object *exception, zend_object *add_previo previous = zend_read_property_ex(base_ce, ex, ZSTR_KNOWN(ZEND_STR_PREVIOUS), 1, &rv); if (Z_TYPE_P(previous) == IS_NULL) { zend_update_property_ex(base_ce, ex, ZSTR_KNOWN(ZEND_STR_PREVIOUS), &pv); - GC_REFCOUNT(add_previous)--; + GC_DELREF(add_previous); return; } ex = previous; @@ -547,14 +547,14 @@ static void _build_trace_string(smart_str *str, HashTable *ht, uint32_t num) /* smart_str_append_long(str, num); smart_str_appendc(str, ' '); - file = zend_hash_find(ht, ZSTR_KNOWN(ZEND_STR_FILE)); + file = zend_hash_find_ex(ht, ZSTR_KNOWN(ZEND_STR_FILE), 1); if (file) { if (Z_TYPE_P(file) != IS_STRING) { zend_error(E_WARNING, "Function name is no string"); smart_str_appends(str, "[unknown function]"); } else{ zend_long line; - tmp = zend_hash_find(ht, ZSTR_KNOWN(ZEND_STR_LINE)); + tmp = zend_hash_find_ex(ht, ZSTR_KNOWN(ZEND_STR_LINE), 1); if (tmp) { if (Z_TYPE_P(tmp) == IS_LONG) { line = Z_LVAL_P(tmp); @@ -577,7 +577,7 @@ static void _build_trace_string(smart_str *str, HashTable *ht, uint32_t num) /* TRACE_APPEND_KEY(ZSTR_KNOWN(ZEND_STR_TYPE)); TRACE_APPEND_KEY(ZSTR_KNOWN(ZEND_STR_FUNCTION)); smart_str_appendc(str, '('); - tmp = zend_hash_find(ht, ZSTR_KNOWN(ZEND_STR_ARGS)); + tmp = zend_hash_find_ex(ht, ZSTR_KNOWN(ZEND_STR_ARGS), 1); if (tmp) { if (Z_TYPE_P(tmp) == IS_ARRAY) { size_t last_len = ZSTR_LEN(str->s); @@ -711,9 +711,9 @@ ZEND_METHOD(exception, __toString) zend_string_release(file); zval_ptr_dtor(&trace); - Z_OBJPROP_P(exception)->u.v.nApplyCount++; + Z_PROTECT_RECURSION_P(exception); exception = GET_PROPERTY(exception, ZEND_STR_PREVIOUS); - if (exception && Z_TYPE_P(exception) == IS_OBJECT && Z_OBJPROP_P(exception)->u.v.nApplyCount > 0) { + if (exception && Z_TYPE_P(exception) == IS_OBJECT && Z_IS_RECURSIVE_P(exception)) { break; } } @@ -722,8 +722,8 @@ ZEND_METHOD(exception, __toString) exception = getThis(); /* Reset apply counts */ while (exception && Z_TYPE_P(exception) == IS_OBJECT && (base_ce = i_get_exception_base(exception)) && instanceof_function(Z_OBJCE_P(exception), base_ce)) { - if (Z_OBJPROP_P(exception)->u.v.nApplyCount) { - Z_OBJPROP_P(exception)->u.v.nApplyCount--; + if (Z_IS_RECURSIVE_P(exception)) { + Z_UNPROTECT_RECURSION_P(exception); } else { break; } @@ -743,7 +743,7 @@ ZEND_METHOD(exception, __toString) /* }}} */ /** {{{ Throwable method definition */ -const zend_function_entry zend_funcs_throwable[] = { +static const zend_function_entry zend_funcs_throwable[] = { ZEND_ABSTRACT_ME(throwable, getMessage, NULL) ZEND_ABSTRACT_ME(throwable, getCode, NULL) ZEND_ABSTRACT_ME(throwable, getFile, NULL) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index ae9d00684d..aaa45a8d4a 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -70,12 +70,20 @@ # define EXECUTE_DATA_DC # define EXECUTE_DATA_CC # define NO_EXECUTE_DATA_CC +# define OPLINE_D void +# define OPLINE_C +# define OPLINE_DC +# define OPLINE_CC #else # define EXECUTE_DATA_D zend_execute_data* execute_data # define EXECUTE_DATA_C execute_data # define EXECUTE_DATA_DC , EXECUTE_DATA_D # define EXECUTE_DATA_CC , EXECUTE_DATA_C # define NO_EXECUTE_DATA_CC , NULL +# define OPLINE_D const zend_op* opline +# define OPLINE_C opline +# define OPLINE_DC , OPLINE_D +# define OPLINE_CC , OPLINE_C #endif #if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) @@ -93,15 +101,15 @@ typedef int (ZEND_FASTCALL *incdec_t)(zval *); -#define get_zval_ptr(op_type, node, should_free, type) _get_zval_ptr(op_type, node, should_free, type EXECUTE_DATA_CC) -#define get_zval_ptr_deref(op_type, node, should_free, type) _get_zval_ptr_deref(op_type, node, should_free, type EXECUTE_DATA_CC) -#define get_zval_ptr_r(op_type, node, should_free) _get_zval_ptr_r(op_type, node, should_free EXECUTE_DATA_CC) -#define get_zval_ptr_r_deref(op_type, node, should_free) _get_zval_ptr_r_deref(op_type, node, should_free EXECUTE_DATA_CC) -#define get_zval_ptr_undef(op_type, node, should_free, type) _get_zval_ptr_undef(op_type, node, should_free, type EXECUTE_DATA_CC) +#define get_zval_ptr(op_type, node, should_free, type) _get_zval_ptr(op_type, node, should_free, type EXECUTE_DATA_CC OPLINE_CC) +#define get_zval_ptr_deref(op_type, node, should_free, type) _get_zval_ptr_deref(op_type, node, should_free, type EXECUTE_DATA_CC OPLINE_CC) +#define get_zval_ptr_undef(op_type, node, should_free, type) _get_zval_ptr_undef(op_type, node, should_free, type EXECUTE_DATA_CC OPLINE_CC) +#define get_op_data_zval_ptr_r(op_type, node, should_free) _get_op_data_zval_ptr_r(op_type, node, should_free EXECUTE_DATA_CC OPLINE_CC) +#define get_op_data_zval_ptr_deref_r(op_type, node, should_free) _get_op_data_zval_ptr_deref_r(op_type, node, should_free EXECUTE_DATA_CC OPLINE_CC) #define get_zval_ptr_ptr(op_type, node, should_free, type) _get_zval_ptr_ptr(op_type, node, should_free, type EXECUTE_DATA_CC) #define get_zval_ptr_ptr_undef(op_type, node, should_free, type) _get_zval_ptr_ptr(op_type, node, should_free, type EXECUTE_DATA_CC) -#define get_obj_zval_ptr(op_type, node, should_free, type) _get_obj_zval_ptr(op_type, node, should_free, type EXECUTE_DATA_CC) -#define get_obj_zval_ptr_undef(op_type, node, should_free, type) _get_obj_zval_ptr_undef(op_type, node, should_free, type EXECUTE_DATA_CC) +#define get_obj_zval_ptr(op_type, node, should_free, type) _get_obj_zval_ptr(op_type, node, should_free, type EXECUTE_DATA_CC OPLINE_CC) +#define get_obj_zval_ptr_undef(op_type, node, should_free, type) _get_obj_zval_ptr_undef(op_type, node, should_free, type EXECUTE_DATA_CC OPLINE_CC) #define get_obj_zval_ptr_ptr(op_type, node, should_free, type) _get_obj_zval_ptr_ptr(op_type, node, should_free, type EXECUTE_DATA_CC) #define RETURN_VALUE_USED(opline) ((opline)->result_type != IS_UNUSED) @@ -159,9 +167,6 @@ ZEND_API const zend_internal_function zend_pass_function = { #define ZEND_VM_STACK_PAGE_SIZE (ZEND_VM_STACK_PAGE_SLOTS * sizeof(zval)) -#define ZEND_VM_STACK_FREE_PAGE_SIZE \ - ((ZEND_VM_STACK_PAGE_SLOTS - ZEND_VM_STACK_HEADER_SLOTS) * sizeof(zval)) - #define ZEND_VM_STACK_PAGE_ALIGNED_SIZE(size) \ (((size) + ZEND_VM_STACK_HEADER_SLOTS * sizeof(zval) \ + (ZEND_VM_STACK_PAGE_SIZE - 1)) & ~(ZEND_VM_STACK_PAGE_SIZE - 1)) @@ -177,6 +182,7 @@ static zend_always_inline zend_vm_stack zend_vm_stack_new_page(size_t size, zend ZEND_API void zend_vm_stack_init(void) { + EG(vm_stack_page_size) = ZEND_VM_STACK_PAGE_SIZE; EG(vm_stack) = zend_vm_stack_new_page(ZEND_VM_STACK_PAGE_SIZE, NULL); EG(vm_stack)->top++; EG(vm_stack_top) = EG(vm_stack)->top; @@ -202,8 +208,8 @@ ZEND_API void* zend_vm_stack_extend(size_t size) stack = EG(vm_stack); stack->top = EG(vm_stack_top); EG(vm_stack) = stack = zend_vm_stack_new_page( - EXPECTED(size < ZEND_VM_STACK_FREE_PAGE_SIZE) ? - ZEND_VM_STACK_PAGE_SIZE : ZEND_VM_STACK_PAGE_ALIGNED_SIZE(size), + EXPECTED(size < EG(vm_stack_page_size) - (ZEND_VM_STACK_HEADER_SLOTS * sizeof(zval))) ? + EG(vm_stack_page_size) : ZEND_VM_STACK_PAGE_ALIGNED_SIZE(size), stack); ptr = stack->top; EG(vm_stack_top) = (void*)(((char*)ptr) + size); @@ -435,7 +441,7 @@ static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_W(uint32_t var EXE return ret; } -static zend_always_inline zval *_get_zval_ptr(int op_type, znode_op node, zend_free_op *should_free, int type EXECUTE_DATA_DC) +static zend_always_inline zval *_get_zval_ptr(int op_type, znode_op node, zend_free_op *should_free, int type EXECUTE_DATA_DC OPLINE_DC) { if (op_type & (IS_TMP_VAR|IS_VAR)) { if (op_type == IS_TMP_VAR) { @@ -447,7 +453,7 @@ static zend_always_inline zval *_get_zval_ptr(int op_type, znode_op node, zend_f } else { *should_free = NULL; if (op_type == IS_CONST) { - return EX_CONSTANT(node); + return RT_CONSTANT(opline, node); } else if (op_type == IS_CV) { return _get_zval_ptr_cv(node.var, type EXECUTE_DATA_CC); } else { @@ -456,7 +462,7 @@ static zend_always_inline zval *_get_zval_ptr(int op_type, znode_op node, zend_f } } -static zend_always_inline zval *_get_zval_ptr_r(int op_type, znode_op node, zend_free_op *should_free EXECUTE_DATA_DC) +static zend_always_inline zval *_get_op_data_zval_ptr_r(int op_type, znode_op node, zend_free_op *should_free EXECUTE_DATA_DC OPLINE_DC) { if (op_type & (IS_TMP_VAR|IS_VAR)) { if (op_type == IS_TMP_VAR) { @@ -468,7 +474,7 @@ static zend_always_inline zval *_get_zval_ptr_r(int op_type, znode_op node, zend } else { *should_free = NULL; if (op_type == IS_CONST) { - return EX_CONSTANT(node); + return RT_CONSTANT(opline + 1, node); } else if (op_type == IS_CV) { return _get_zval_ptr_cv_BP_VAR_R(node.var EXECUTE_DATA_CC); } else { @@ -477,7 +483,7 @@ static zend_always_inline zval *_get_zval_ptr_r(int op_type, znode_op node, zend } } -static zend_always_inline zval *_get_zval_ptr_deref(int op_type, znode_op node, zend_free_op *should_free, int type EXECUTE_DATA_DC) +static zend_always_inline zval *_get_zval_ptr_deref(int op_type, znode_op node, zend_free_op *should_free, int type EXECUTE_DATA_DC OPLINE_DC) { if (op_type & (IS_TMP_VAR|IS_VAR)) { if (op_type == IS_TMP_VAR) { @@ -489,7 +495,7 @@ static zend_always_inline zval *_get_zval_ptr_deref(int op_type, znode_op node, } else { *should_free = NULL; if (op_type == IS_CONST) { - return EX_CONSTANT(node); + return RT_CONSTANT(opline, node); } else if (op_type == IS_CV) { return _get_zval_ptr_cv_deref(node.var, type EXECUTE_DATA_CC); } else { @@ -498,7 +504,7 @@ static zend_always_inline zval *_get_zval_ptr_deref(int op_type, znode_op node, } } -static zend_always_inline zval *_get_zval_ptr_r_deref(int op_type, znode_op node, zend_free_op *should_free EXECUTE_DATA_DC) +static zend_always_inline zval *_get_op_data_zval_ptr_deref_r(int op_type, znode_op node, zend_free_op *should_free EXECUTE_DATA_DC OPLINE_DC) { if (op_type & (IS_TMP_VAR|IS_VAR)) { if (op_type == IS_TMP_VAR) { @@ -510,7 +516,7 @@ static zend_always_inline zval *_get_zval_ptr_r_deref(int op_type, znode_op node } else { *should_free = NULL; if (op_type == IS_CONST) { - return EX_CONSTANT(node); + return RT_CONSTANT(opline + 1, node); } else if (op_type == IS_CV) { return _get_zval_ptr_cv_deref_BP_VAR_R(node.var EXECUTE_DATA_CC); } else { @@ -519,7 +525,7 @@ static zend_always_inline zval *_get_zval_ptr_r_deref(int op_type, znode_op node } } -static zend_always_inline zval *_get_zval_ptr_undef(int op_type, znode_op node, zend_free_op *should_free, int type EXECUTE_DATA_DC) +static zend_always_inline zval *_get_zval_ptr_undef(int op_type, znode_op node, zend_free_op *should_free, int type EXECUTE_DATA_DC OPLINE_DC) { if (op_type & (IS_TMP_VAR|IS_VAR)) { if (op_type == IS_TMP_VAR) { @@ -531,7 +537,7 @@ static zend_always_inline zval *_get_zval_ptr_undef(int op_type, znode_op node, } else { *should_free = NULL; if (op_type == IS_CONST) { - return EX_CONSTANT(node); + return RT_CONSTANT(opline, node); } else if (op_type == IS_CV) { return _get_zval_ptr_cv_undef(node.var EXECUTE_DATA_CC); } else { @@ -569,7 +575,7 @@ static zend_always_inline zval *_get_obj_zval_ptr_unused(EXECUTE_DATA_D) return &EX(This); } -static inline zval *_get_obj_zval_ptr(int op_type, znode_op op, zend_free_op *should_free, int type EXECUTE_DATA_DC) +static inline zval *_get_obj_zval_ptr(int op_type, znode_op op, zend_free_op *should_free, int type EXECUTE_DATA_DC OPLINE_DC) { if (op_type == IS_UNUSED) { *should_free = NULL; @@ -578,7 +584,7 @@ static inline zval *_get_obj_zval_ptr(int op_type, znode_op op, zend_free_op *sh return get_zval_ptr(op_type, op, should_free, type); } -static inline zval *_get_obj_zval_ptr_undef(int op_type, znode_op op, zend_free_op *should_free, int type EXECUTE_DATA_DC) +static inline zval *_get_obj_zval_ptr_undef(int op_type, znode_op op, zend_free_op *should_free, int type EXECUTE_DATA_DC OPLINE_DC) { if (op_type == IS_UNUSED) { *should_free = NULL; @@ -607,11 +613,11 @@ static inline void zend_assign_to_variable_reference(zval *variable_ptr, zval *v } ref = Z_REF_P(value_ptr); - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); if (Z_REFCOUNTED_P(variable_ptr)) { zend_refcounted *garbage = Z_COUNTED_P(variable_ptr); - if (--GC_REFCOUNT(garbage) == 0) { + if (GC_DELREF(garbage) == 0) { ZVAL_REF(variable_ptr, ref); zval_dtor_func(garbage); return; @@ -743,7 +749,7 @@ static ZEND_COLD void zend_verify_arg_error( static int is_null_constant(zend_class_entry *scope, zval *default_value) { - if (Z_CONSTANT_P(default_value)) { + if (Z_TYPE_P(default_value) == IS_CONSTANT_AST) { zval constant; ZVAL_COPY(&constant, default_value); @@ -753,7 +759,7 @@ static int is_null_constant(zend_class_entry *scope, zval *default_value) if (Z_TYPE(constant) == IS_NULL) { return 1; } - zval_ptr_dtor(&constant); + zval_ptr_dtor_nogc(&constant); } return 0; } @@ -1110,7 +1116,7 @@ try_again: break; } - offset = _zval_get_long_func(dim); + offset = zval_get_long_func(dim); } else { offset = Z_LVAL_P(dim); } @@ -1144,6 +1150,7 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(EXECUTE_DATA_D) case ZEND_FETCH_DIM_RW: case ZEND_FETCH_DIM_FUNC_ARG: case ZEND_FETCH_DIM_UNSET: + case ZEND_FETCH_LIST_W: /* TODO: Encode the "reason" into opline->extended_value??? */ var = opline->result.var; opline++; @@ -1186,6 +1193,7 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(EXECUTE_DATA_D) case ZEND_FETCH_DIM_RW: case ZEND_FETCH_DIM_FUNC_ARG: case ZEND_FETCH_DIM_UNSET: + case ZEND_FETCH_LIST_W: case ZEND_ASSIGN_DIM: msg = "Cannot use string offset as an array"; break; @@ -1234,7 +1242,7 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(EXECUTE_DATA_D) EMPTY_SWITCH_DEFAULT_CASE(); } ZEND_ASSERT(msg != NULL); - zend_throw_error(NULL, msg); + zend_throw_error(NULL, "%s", msg); } static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim, zval *value, zval *result EXECUTE_DATA_DC) @@ -1256,7 +1264,7 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim, if (Z_TYPE_P(value) != IS_STRING) { /* Convert to string, just the time to pick the 1st byte */ - zend_string *tmp = zval_get_string(value); + zend_string *tmp = zval_get_string_func(value); string_len = ZSTR_LEN(tmp); c = (zend_uchar)ZSTR_VAL(tmp)[0]; @@ -1378,7 +1386,6 @@ static zend_never_inline void zend_pre_incdec_overloaded_property(zval *object, ZVAL_COPY_VALUE(z, value); } ZVAL_DEREF(z); - SEPARATE_ZVAL_NOREF(z); if (inc) { increment_function(z); } else { @@ -1426,7 +1433,6 @@ static zend_never_inline void zend_assign_op_overloaded_property(zval *object, z } zptr = z; ZVAL_DEREF(z); - SEPARATE_ZVAL_NOREF(z); binary_op(z, z, value); Z_OBJ_HT(obj)->write_property(&obj, property, z, cache_slot); if (UNEXPECTED(result)) { @@ -1521,7 +1527,7 @@ num_undef: } } str_index: - retval = zend_hash_find(ht, offset_key); + retval = zend_hash_find_ex(ht, offset_key, dim_type == IS_CONST); if (retval) { /* support for $GLOBALS[...] */ if (UNEXPECTED(Z_TYPE_P(retval) == IS_INDIRECT)) { @@ -1698,8 +1704,7 @@ fetch_from_array: } if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { if (type != BP_VAR_UNSET) { - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + array_init(container); goto fetch_from_array; } else { /* for read-mode only */ @@ -1786,7 +1791,7 @@ try_string_offset: break; } - offset = _zval_get_long_func(dim); + offset = zval_get_long_func(dim); } else { offset = Z_LVAL_P(dim); } @@ -1854,7 +1859,12 @@ static zend_never_inline void zend_fetch_dimension_address_read_IS(zval *result, zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS, 1, 0 EXECUTE_DATA_CC); } -static zend_never_inline void zend_fetch_dimension_address_read_LIST(zval *result, zval *container, zval *dim EXECUTE_DATA_DC) +static zend_never_inline void zend_fetch_dimension_address_LIST_w(zval *result, zval *container, zval *dim EXECUTE_DATA_DC) +{ + zend_fetch_dimension_address(result, container, dim, IS_TMP_VAR, BP_VAR_W EXECUTE_DATA_CC); +} + +static zend_never_inline void zend_fetch_dimension_address_LIST_r(zval *result, zval *container, zval *dim EXECUTE_DATA_DC) { zend_fetch_dimension_address_read(result, container, dim, IS_TMP_VAR, BP_VAR_R, 0, 0 EXECUTE_DATA_CC); } @@ -1862,9 +1872,9 @@ static zend_never_inline void zend_fetch_dimension_address_read_LIST(zval *resul ZEND_API void zend_fetch_dimension_const(zval *result, zval *container, zval *dim, int type) { if (type == BP_VAR_IS) { - zend_fetch_dimension_address_read_IS(result, container, dim, IS_CONST NO_EXECUTE_DATA_CC); + zend_fetch_dimension_address_read_IS(result, container, dim, IS_TMP_VAR NO_EXECUTE_DATA_CC); } else { - zend_fetch_dimension_address_read_R(result, container, dim, IS_CONST NO_EXECUTE_DATA_CC); + zend_fetch_dimension_address_read_R(result, container, dim, IS_TMP_VAR NO_EXECUTE_DATA_CC); } } @@ -1898,11 +1908,11 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c } if (prop_op_type == IS_CONST && EXPECTED(Z_OBJCE_P(container) == CACHED_PTR_EX(cache_slot))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR_EX(cache_slot + 1); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_INDIRECT(result, retval); @@ -1911,11 +1921,11 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c } else if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - retval = zend_hash_find(zobj->properties, Z_STR_P(prop_ptr)); + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(prop_ptr), 1); if (EXPECTED(retval)) { ZVAL_INDIRECT(result, retval); return; @@ -1948,22 +1958,22 @@ use_read_property: } } -static zend_always_inline zval* zend_fetch_static_property_address(zval *varname, zend_uchar varname_type, znode_op op2, zend_uchar op2_type, int type EXECUTE_DATA_DC) +static zend_always_inline zval* zend_fetch_static_property_address(zval *varname, zend_uchar varname_type, znode_op op2, zend_uchar op2_type, int type EXECUTE_DATA_DC OPLINE_DC) { zval *retval; - zend_string *name; + zend_string *name, *tmp_name; zend_class_entry *ce; if (varname_type == IS_CONST) { name = Z_STR_P(varname); } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { name = Z_STR_P(varname); - zend_string_addref(name); + tmp_name = NULL; } else { if (varname_type == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { zval_undefined_cv(EX(opline)->op1.var EXECUTE_DATA_CC); } - name = zval_get_string(varname); + name = zval_get_tmp_string(varname, &tmp_name); } if (op2_type == IS_CONST) { @@ -1980,13 +1990,13 @@ static zend_always_inline zval* zend_fetch_static_property_address(zval *varname return retval; } else { - zval *class_name = EX_CONSTANT(op2); + zval *class_name = RT_CONSTANT(opline, op2); if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(class_name))) == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(class_name), class_name + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { if (varname_type != IS_CONST) { - zend_string_release(name); + zend_tmp_string_release(tmp_name); } return NULL; } @@ -1998,7 +2008,7 @@ static zend_always_inline zval* zend_fetch_static_property_address(zval *varname ce = zend_fetch_class(NULL, op2.num); if (UNEXPECTED(ce == NULL)) { if (varname_type != IS_CONST) { - zend_string_release(name); + zend_tmp_string_release(tmp_name); } return NULL; } @@ -2024,7 +2034,7 @@ static zend_always_inline zval* zend_fetch_static_property_address(zval *varname retval = zend_std_get_static_property(ce, name, type == BP_VAR_IS); if (varname_type != IS_CONST) { - zend_string_release(name); + zend_tmp_string_release(tmp_name); } if (UNEXPECTED(retval == NULL)) { @@ -2093,11 +2103,11 @@ ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table) /* {{{ static zend_always_inline void i_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */ { zval *cv = EX_VAR_NUM(0); - zval *end = cv + EX(func)->op_array.last_var; - while (EXPECTED(cv != end)) { + int count = EX(func)->op_array.last_var; + while (EXPECTED(count != 0)) { if (Z_REFCOUNTED_P(cv)) { zend_refcounted *r = Z_COUNTED_P(cv); - if (!--GC_REFCOUNT(r)) { + if (!GC_DELREF(r)) { ZVAL_NULL(cv); zval_dtor_func(r); } else { @@ -2105,11 +2115,12 @@ static zend_always_inline void i_free_compiled_variables(zend_execute_data *exec } } cv++; - } + count--; + } } /* }}} */ -void zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */ +ZEND_API void zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */ { i_free_compiled_variables(execute_data); } @@ -2147,12 +2158,70 @@ void zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */ * +----------------------------------------+ */ -static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */ +static zend_never_inline void zend_copy_extra_args(EXECUTE_DATA_D) +{ + zend_op_array *op_array = &EX(func)->op_array; + uint32_t first_extra_arg = op_array->num_args; + uint32_t num_args = EX_NUM_ARGS(); + zval *src; + size_t delta; + uint32_t count; + uint32_t type_flags = 0; + + if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) { + /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */ +#if defined(ZEND_VM_FP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + opline += first_extra_arg; +#else + EX(opline) += first_extra_arg; +#endif + + } + + /* move extra args into separate array after all CV and TMP vars */ + src = EX_VAR_NUM(num_args - 1); + delta = op_array->last_var + op_array->T - first_extra_arg; + count = num_args - first_extra_arg; + if (EXPECTED(delta != 0)) { + delta *= sizeof(zval); + do { + type_flags |= Z_TYPE_INFO_P(src); + ZVAL_COPY_VALUE((zval*)(((char*)src) + delta), src); + ZVAL_UNDEF(src); + src--; + } while (--count); + } else { + do { + type_flags |= Z_TYPE_INFO_P(src); + src--; + } while (--count); + } + ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED)); +} + +static zend_always_inline void zend_init_cvs(uint32_t first, uint32_t last EXECUTE_DATA_DC) +{ + if (EXPECTED(first < last)) { + uint32_t count = last - first; + zval *var = EX_VAR_NUM(first); + + do { + ZVAL_UNDEF(var); + var++; + } while (--count); + } +} + +static zend_always_inline void i_init_func_execute_data(zend_op_array *op_array, zval *return_value, zend_bool may_be_trampoline EXECUTE_DATA_DC) /* {{{ */ { uint32_t first_extra_arg, num_args; ZEND_ASSERT(EX(func) == (zend_function*)op_array); +#if defined(ZEND_VM_FP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + opline = op_array->opcodes; +#else EX(opline) = op_array->opcodes; +#endif EX(call) = NULL; EX(return_value) = return_value; @@ -2160,55 +2229,27 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu first_extra_arg = op_array->num_args; num_args = EX_NUM_ARGS(); if (UNEXPECTED(num_args > first_extra_arg)) { - if (EXPECTED(!(op_array->fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))) { - zval *end, *src, *dst; - uint32_t type_flags = 0; - - if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) { - /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */ - EX(opline) += first_extra_arg; - } - - /* move extra args into separate array after all CV and TMP vars */ - end = EX_VAR_NUM(first_extra_arg - 1); - src = end + (num_args - first_extra_arg); - dst = src + (op_array->last_var + op_array->T - first_extra_arg); - if (EXPECTED(src != dst)) { - do { - type_flags |= Z_TYPE_INFO_P(src); - ZVAL_COPY_VALUE(dst, src); - ZVAL_UNDEF(src); - src--; - dst--; - } while (src != end); - } else { - do { - type_flags |= Z_TYPE_INFO_P(src); - src--; - } while (src != end); - } - ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED)); + if (!may_be_trampoline || EXPECTED(!(op_array->fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))) { + zend_copy_extra_args(EXECUTE_DATA_C); } } else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) { /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */ +#if defined(ZEND_VM_FP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + opline += num_args; +#else EX(opline) += num_args; +#endif } /* Initialize CV variables (skip arguments) */ - if (EXPECTED((int)num_args < op_array->last_var)) { - zval *var = EX_VAR_NUM(num_args); - zval *end = EX_VAR_NUM(op_array->last_var); - - do { - ZVAL_UNDEF(var); - var++; - } while (var != end); - } + zend_init_cvs(num_args, op_array->last_var EXECUTE_DATA_CC); EX_LOAD_RUN_TIME_CACHE(op_array); - EX_LOAD_LITERALS(op_array); EG(current_execute_data) = execute_data; +#if defined(ZEND_VM_FP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + EX(opline) = opline; +#endif } /* }}} */ @@ -2235,20 +2276,33 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu memset(op_array->run_time_cache, 0, op_array->cache_size); } EX_LOAD_RUN_TIME_CACHE(op_array); - EX_LOAD_LITERALS(op_array); EG(current_execute_data) = execute_data; } /* }}} */ -ZEND_API void zend_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */ +ZEND_API void zend_init_func_execute_data(zend_execute_data *ex, zend_op_array *op_array, zval *return_value) /* {{{ */ { +#if defined(ZEND_VM_FP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + zend_execute_data *orig_execute_data = execute_data; + const zend_op *orig_opline = opline; + execute_data = ex; +#else + zend_execute_data *execute_data = ex; +#endif + EX(prev_execute_data) = EG(current_execute_data); if (!op_array->run_time_cache) { op_array->run_time_cache = zend_arena_alloc(&CG(arena), op_array->cache_size); memset(op_array->run_time_cache, 0, op_array->cache_size); } - i_init_func_execute_data(execute_data, op_array, return_value); + i_init_func_execute_data(op_array, return_value, 1 EXECUTE_DATA_CC); + +#if defined(ZEND_VM_FP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + EX(opline) = opline; + opline = orig_opline; + execute_data = orig_execute_data; +#endif } /* }}} */ @@ -2447,7 +2501,7 @@ static void cleanup_unfinished_calls(zend_execute_data *execute_data, uint32_t o if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) { if (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR) { - GC_REFCOUNT(Z_OBJ(call->This))--; + GC_DELREF(Z_OBJ(call->This)); if (GC_REFCOUNT(Z_OBJ(call->This)) == 1) { zend_object_store_ctor_failed(Z_OBJ(call->This)); } @@ -2519,7 +2573,7 @@ static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num, } /* }}} */ -void zend_cleanup_unfinished_execution(zend_execute_data *execute_data, uint32_t op_num, uint32_t catch_op_num) { +ZEND_API void zend_cleanup_unfinished_execution(zend_execute_data *execute_data, uint32_t op_num, uint32_t catch_op_num) { cleanup_unfinished_calls(execute_data, op_num); cleanup_live_vars(execute_data, op_num, catch_op_num); } @@ -2637,14 +2691,14 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zval * if (fbc->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ ZEND_ASSERT(GC_TYPE((zend_object*)fbc->common.prototype) == IS_OBJECT); - GC_REFCOUNT((zend_object*)fbc->common.prototype)++; + GC_ADDREF((zend_object*)fbc->common.prototype); call_info |= ZEND_CALL_CLOSURE; if (fbc->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { call_info |= ZEND_CALL_FAKE_CLOSURE; } } else if (object) { call_info |= ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(object)++; /* For $this pointer */ + GC_ADDREF(object); /* For $this pointer */ } } else { zend_throw_error(NULL, "Function name must be a string"); @@ -2740,7 +2794,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_ar object = NULL; } else { call_info |= ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(object)++; /* For $this pointer */ + GC_ADDREF(object); /* For $this pointer */ } } } else { @@ -2766,7 +2820,7 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval ZVAL_UNDEF(&tmp_inc_filename); if (Z_TYPE_P(inc_filename) != IS_STRING) { - ZVAL_STR(&tmp_inc_filename, zval_get_string(inc_filename)); + ZVAL_STR(&tmp_inc_filename, zval_get_string_func(inc_filename)); inc_filename = &tmp_inc_filename; } @@ -2783,7 +2837,7 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval zend_file_handle file_handle; zend_string *resolved_path; - resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), (int)Z_STRLEN_P(inc_filename)); + resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename)); if (resolved_path) { if (zend_hash_exists(&EG(included_files), resolved_path)) { goto already_compiled; @@ -2997,8 +3051,18 @@ ZEND_API int ZEND_FASTCALL zend_do_fcall_overloaded(zend_execute_data *call, zva } \ } while (0) +#if ZEND_GCC_VERSION >= 4000 +# pragma GCC push_options +# pragma GCC optimize("no-gcse") +# pragma GCC optimize("no-ivopts") +#endif + #include "zend_vm_execute.h" +#if ZEND_GCC_VERSION >= 4000 +# pragma GCC pop_options +#endif + ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler) { if (opcode != ZEND_USER_OPCODE) { @@ -3019,13 +3083,13 @@ ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode) return zend_user_opcode_handlers[opcode]; } -ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type) +ZEND_API zval *zend_get_zval_ptr(const zend_op *opline, int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type) { zval *ret; switch (op_type) { case IS_CONST: - ret = EX_CONSTANT(*node); + ret = RT_CONSTANT(opline, *node); *should_free = NULL; break; case IS_TMP_VAR: diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 7edba6f2a5..77246981ca 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -85,19 +85,19 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval if (ZEND_CONST_COND(value_type & (IS_VAR|IS_CV), 1) && variable_ptr == value) { if (value_type == IS_VAR && ref) { ZEND_ASSERT(GC_REFCOUNT(ref) > 1); - --GC_REFCOUNT(ref); + GC_DELREF(ref); } return variable_ptr; } garbage = Z_COUNTED_P(variable_ptr); - if (--GC_REFCOUNT(garbage) == 0) { + if (GC_DELREF(garbage) == 0) { ZVAL_COPY_VALUE(variable_ptr, value); if (value_type & (IS_CONST|IS_CV)) { if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { Z_ADDREF_P(variable_ptr); } } else if (ZEND_CONST_COND(value_type == IS_VAR, 1) && UNEXPECTED(ref)) { - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(variable_ptr)) { Z_ADDREF_P(variable_ptr); @@ -120,7 +120,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval Z_ADDREF_P(variable_ptr); } } else if (ZEND_CONST_COND(value_type == IS_VAR, 1) && UNEXPECTED(ref)) { - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(variable_ptr)) { Z_ADDREF_P(variable_ptr); @@ -131,6 +131,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval ZEND_API int zval_update_constant(zval *pp); ZEND_API int zval_update_constant_ex(zval *pp, zend_class_entry *scope); +ZEND_API int zend_use_undefined_constant(zend_string *name, zend_ast_attr attr, zval *result); /* dedicated Zend executor functions - do not use! */ struct _zend_vm_stack { @@ -216,20 +217,20 @@ static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(uint3 static zend_always_inline void zend_vm_stack_free_extra_args_ex(uint32_t call_info, zend_execute_data *call) { if (UNEXPECTED(call_info & ZEND_CALL_FREE_EXTRA_ARGS)) { - zval *end = ZEND_CALL_VAR_NUM(call, call->func->op_array.last_var + call->func->op_array.T); - zval *p = end + (ZEND_CALL_NUM_ARGS(call) - call->func->op_array.num_args); + uint32_t count = ZEND_CALL_NUM_ARGS(call) - call->func->op_array.num_args; + zval *p = ZEND_CALL_VAR_NUM(call, call->func->op_array.last_var + call->func->op_array.T + count); do { p--; if (Z_REFCOUNTED_P(p)) { zend_refcounted *r = Z_COUNTED_P(p); - if (!--GC_REFCOUNT(r)) { + if (!GC_DELREF(r)) { ZVAL_NULL(p); zval_dtor_func(r); } else { gc_check_possible_root(r); } } - } while (p != end); + } while (--count); } } @@ -318,11 +319,11 @@ ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode); /* former zend_execute_locks.h */ typedef zval* zend_free_op; -ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type); +ZEND_API zval *zend_get_zval_ptr(const zend_op *opline, int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type); ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table); -void zend_free_compiled_variables(zend_execute_data *execute_data); -void zend_cleanup_unfinished_execution(zend_execute_data *execute_data, uint32_t op_num, uint32_t catch_op_num); +ZEND_API void zend_free_compiled_variables(zend_execute_data *execute_data); +ZEND_API void zend_cleanup_unfinished_execution(zend_execute_data *execute_data, uint32_t op_num, uint32_t catch_op_num); ZEND_API int ZEND_FASTCALL zend_do_fcall_overloaded(zend_execute_data *call, zval *ret); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index a619b3ccf3..8e366ca75c 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -333,7 +333,7 @@ void shutdown_executor(void) /* {{{ */ if (c->flags & CONST_PERSISTENT) { break; } - zval_ptr_dtor(&c->value); + zval_ptr_dtor_nogc(&c->value); if (c->name) { zend_string_release(c->name); } @@ -542,90 +542,64 @@ ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ * } /* }}} */ -ZEND_API int zval_update_constant_ex(zval *p, zend_class_entry *scope) /* {{{ */ +ZEND_API int zend_use_undefined_constant(zend_string *name, zend_ast_attr attr, zval *result) /* {{{ */ { - zval *const_value; char *colon; - zend_bool inline_change; - if (Z_TYPE_P(p) == IS_CONSTANT) { - if (IS_CONSTANT_VISITED(p)) { - zend_throw_error(NULL, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p)); + if (UNEXPECTED(EG(exception))) { + return FAILURE; + } else if ((colon = (char*)zend_memrchr(ZSTR_VAL(name), ':', ZSTR_LEN(name)))) { + zend_throw_error(NULL, "Undefined class constant '%s'", ZSTR_VAL(name)); + return FAILURE; + } else if ((attr & IS_CONSTANT_UNQUALIFIED) == 0) { + zend_throw_error(NULL, "Undefined constant '%s'", ZSTR_VAL(name)); + return FAILURE; + } else { + char *actual = ZSTR_VAL(name); + size_t actual_len = ZSTR_LEN(name); + char *slash = (char *) zend_memrchr(actual, '\\', actual_len); + + if (slash) { + actual = slash + 1; + actual_len -= (actual - ZSTR_VAL(name)); + } + + zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)", actual, actual); + if (EG(exception)) { return FAILURE; + } else { + zend_string *result_str = zend_string_init(actual, actual_len, 0); + zval_ptr_dtor_nogc(result); + ZVAL_NEW_STR(result, result_str); } - inline_change = (Z_TYPE_FLAGS_P(p) & IS_TYPE_REFCOUNTED) != 0; - SEPARATE_ZVAL_NOREF(p); - MARK_CONSTANT_VISITED(p); - if (Z_CONST_FLAGS_P(p) & IS_CONSTANT_CLASS) { - ZEND_ASSERT(EG(current_execute_data)); - if (inline_change) { - zend_string_release(Z_STR_P(p)); - } - if (scope && scope->name) { - ZVAL_STR_COPY(p, scope->name); - } else { - ZVAL_EMPTY_STRING(p); - } - } else if (UNEXPECTED((const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p))) == NULL)) { - if (UNEXPECTED(EG(exception))) { - RESET_CONSTANT_VISITED(p); - return FAILURE; - } else if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { - zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(p)); - RESET_CONSTANT_VISITED(p); - return FAILURE; - } else { - if ((Z_CONST_FLAGS_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) { - zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(p)); - RESET_CONSTANT_VISITED(p); - return FAILURE; - } else { - zend_string *save = Z_STR_P(p); - char *actual = Z_STRVAL_P(p); - size_t actual_len = Z_STRLEN_P(p); - char *slash = (char *) zend_memrchr(actual, '\\', actual_len); - if (slash) { - actual = slash + 1; - actual_len -= (actual - Z_STRVAL_P(p)); - } + } + return SUCCESS; +} +/* }}} */ - zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)", actual, actual); - if (EG(exception)) { - RESET_CONSTANT_VISITED(p); - return FAILURE; - } +ZEND_API int zval_update_constant_ex(zval *p, zend_class_entry *scope) /* {{{ */ +{ + if (Z_TYPE_P(p) == IS_CONSTANT_AST) { + zend_ast *ast = Z_ASTVAL_P(p); - if (!inline_change) { - ZVAL_STRINGL(p, actual, actual_len); - } else { - if (slash) { - ZVAL_STRINGL(p, actual, actual_len); - zend_string_release(save); - } else { - Z_TYPE_INFO_P(p) = Z_REFCOUNTED_P(p) ? - IS_STRING_EX : IS_INTERNED_STRING_EX; - } - } - } + if (ast->kind == ZEND_AST_CONSTANT) { + zend_string *name = zend_ast_get_constant_name(ast); + zval *zv = zend_get_constant_ex(name, scope, ast->attr); + + if (UNEXPECTED(zv == NULL)) { + return zend_use_undefined_constant(name, ast->attr, p); } + zval_ptr_dtor_nogc(p); + ZVAL_COPY_OR_DUP(p, zv); } else { - if (inline_change) { - zend_string_release(Z_STR_P(p)); - } - ZVAL_COPY_VALUE(p, const_value); - zval_opt_copy_ctor(p); - } - } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { - zval tmp; + zval tmp; - inline_change = (Z_TYPE_FLAGS_P(p) & IS_TYPE_REFCOUNTED) != 0; - if (UNEXPECTED(zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope) != SUCCESS)) { - return FAILURE; - } - if (inline_change) { - zval_ptr_dtor(p); + if (UNEXPECTED(zend_ast_evaluate(&tmp, ast, scope) != SUCCESS)) { + return FAILURE; + } + zval_ptr_dtor_nogc(p); + ZVAL_COPY_VALUE(p, &tmp); } - ZVAL_COPY_VALUE(p, &tmp); } return SUCCESS; } @@ -801,7 +775,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / uint32_t call_info; ZEND_ASSERT(GC_TYPE((zend_object*)func->op_array.prototype) == IS_OBJECT); - GC_REFCOUNT((zend_object*)func->op_array.prototype)++; + GC_ADDREF((zend_object*)func->op_array.prototype); call_info = ZEND_CALL_CLOSURE; if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { call_info |= ZEND_CALL_FAKE_CLOSURE; @@ -932,9 +906,9 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k } if (!EG(autoload_func)) { - zend_function *func = zend_hash_find_ptr(EG(function_table), ZSTR_KNOWN(ZEND_STR_MAGIC_AUTOLOAD)); - if (func) { - EG(autoload_func) = func; + zval *zv = zend_hash_find_ex(EG(function_table), ZSTR_KNOWN(ZEND_STR_MAGIC_AUTOLOAD), 1); + if (zv) { + EG(autoload_func) = (zend_function*)Z_PTR_P(zv); } else { if (!key) { zend_string_release(lc_name); @@ -1052,7 +1026,7 @@ ZEND_API int zend_eval_stringl(char *str, size_t str_len, zval *retval_ptr, char int retval; if (retval_ptr) { - ZVAL_NEW_STR(&pv, zend_string_alloc(str_len + sizeof("return ;")-1, 1)); + ZVAL_NEW_STR(&pv, zend_string_alloc(str_len + sizeof("return ;")-1, 0)); memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1); memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, str, str_len); Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';'; @@ -1527,8 +1501,7 @@ ZEND_API zend_array *zend_rebuild_symbol_table(void) /* {{{ */ } zend_hash_extend(symbol_table, ex->func->op_array.last_var, 0); } else { - symbol_table = ex->symbol_table = emalloc(sizeof(zend_array)); - zend_hash_init(symbol_table, ex->func->op_array.last_var, NULL, ZVAL_PTR_DTOR, 0); + symbol_table = ex->symbol_table = zend_new_array(ex->func->op_array.last_var); if (!ex->func->op_array.last_var) { return symbol_table; } @@ -1563,7 +1536,7 @@ ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ * zval *var = EX_VAR_NUM(0); do { - zval *zv = zend_hash_find(ht, *str); + zval *zv = zend_hash_find_ex(ht, *str, 1); if (zv) { if (Z_TYPE_P(zv) == IS_INDIRECT) { @@ -1629,8 +1602,7 @@ ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force) /* {{ do { if (ZSTR_H(*str) == h && - ZSTR_LEN(*str) == ZSTR_LEN(name) && - memcmp(ZSTR_VAL(*str), ZSTR_VAL(name), ZSTR_LEN(name)) == 0) { + zend_string_equal_content(*str, name)) { zval *var = EX_VAR_NUM(str - op_array->vars); ZVAL_COPY_VALUE(var, value); return SUCCESS; diff --git a/Zend/zend_extensions.c b/Zend/zend_extensions.c index e556eb07bc..8da0914748 100644 --- a/Zend/zend_extensions.c +++ b/Zend/zend_extensions.c @@ -125,14 +125,6 @@ int zend_load_extension_handle(DL_HANDLE handle, const char *path) #endif DL_UNLOAD(handle); return FAILURE; - } else if (zend_get_extension(new_extension->name)) { - fprintf(stderr, "Cannot load %s - extension already loaded\n", new_extension->name); -/* See http://support.microsoft.com/kb/190351 */ -#ifdef PHP_WIN32 - fflush(stderr); -#endif - DL_UNLOAD(handle); - return FAILURE; } return zend_register_extension(new_extension, handle); diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index 818539ae75..437c0801e4 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -282,9 +282,9 @@ ZEND_API void ZEND_FASTCALL gc_possible_root(zend_refcounted *ref) if (!GC_G(gc_enabled)) { return; } - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); gc_collect_cycles(); - GC_REFCOUNT(ref)--; + GC_DELREF(ref); if (UNEXPECTED(GC_REFCOUNT(ref)) == 0) { zval_dtor_func(ref); return; @@ -397,7 +397,7 @@ tail_call: while (zv != end) { if (Z_REFCOUNTED_P(zv)) { ref = Z_COUNTED_P(zv); - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); if (GC_REF_GET_COLOR(ref) != GC_BLACK) { gc_scan_black(ref); } @@ -406,7 +406,7 @@ tail_call: } if (EXPECTED(!ht)) { ref = Z_COUNTED_P(zv); - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); if (GC_REF_GET_COLOR(ref) != GC_BLACK) { goto tail_call; } @@ -424,7 +424,7 @@ tail_call: } else if (GC_TYPE(ref) == IS_REFERENCE) { if (Z_REFCOUNTED(((zend_reference*)ref)->val)) { ref = Z_COUNTED(((zend_reference*)ref)->val); - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); if (GC_REF_GET_COLOR(ref) != GC_BLACK) { goto tail_call; } @@ -455,7 +455,7 @@ tail_call: } if (Z_REFCOUNTED_P(zv)) { ref = Z_COUNTED_P(zv); - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); if (GC_REF_GET_COLOR(ref) != GC_BLACK) { gc_scan_black(ref); } @@ -467,7 +467,7 @@ tail_call: zv = Z_INDIRECT_P(zv); } ref = Z_COUNTED_P(zv); - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); if (GC_REF_GET_COLOR(ref) != GC_BLACK) { goto tail_call; } @@ -507,14 +507,14 @@ tail_call: while (zv != end) { if (Z_REFCOUNTED_P(zv)) { ref = Z_COUNTED_P(zv); - GC_REFCOUNT(ref)--; + GC_DELREF(ref); gc_mark_grey(ref); } zv++; } if (EXPECTED(!ht)) { ref = Z_COUNTED_P(zv); - GC_REFCOUNT(ref)--; + GC_DELREF(ref); goto tail_call; } } else { @@ -530,7 +530,7 @@ tail_call: } else if (GC_TYPE(ref) == IS_REFERENCE) { if (Z_REFCOUNTED(((zend_reference*)ref)->val)) { ref = Z_COUNTED(((zend_reference*)ref)->val); - GC_REFCOUNT(ref)--; + GC_DELREF(ref); goto tail_call; } return; @@ -559,7 +559,7 @@ tail_call: } if (Z_REFCOUNTED_P(zv)) { ref = Z_COUNTED_P(zv); - GC_REFCOUNT(ref)--; + GC_DELREF(ref); gc_mark_grey(ref); } p++; @@ -569,7 +569,7 @@ tail_call: zv = Z_INDIRECT_P(zv); } ref = Z_COUNTED_P(zv); - GC_REFCOUNT(ref)--; + GC_DELREF(ref); goto tail_call; } } @@ -799,7 +799,7 @@ tail_call: while (zv != end) { if (Z_REFCOUNTED_P(zv)) { ref = Z_COUNTED_P(zv); - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); count += gc_collect_white(ref, flags); /* count non-refcounted for compatibility ??? */ } else if (Z_TYPE_P(zv) != IS_UNDEF) { @@ -809,7 +809,7 @@ tail_call: } if (EXPECTED(!ht)) { ref = Z_COUNTED_P(zv); - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); goto tail_call; } } else { @@ -828,7 +828,7 @@ tail_call: } else if (GC_TYPE(ref) == IS_REFERENCE) { if (Z_REFCOUNTED(((zend_reference*)ref)->val)) { ref = Z_COUNTED(((zend_reference*)ref)->val); - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); goto tail_call; } return count; @@ -861,7 +861,7 @@ tail_call: } if (Z_REFCOUNTED_P(zv)) { ref = Z_COUNTED_P(zv); - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); count += gc_collect_white(ref, flags); /* count non-refcounted for compatibility ??? */ } else if (Z_TYPE_P(zv) != IS_UNDEF) { @@ -874,7 +874,7 @@ tail_call: zv = Z_INDIRECT_P(zv); } ref = Z_COUNTED_P(zv); - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); goto tail_call; } return count; @@ -1118,9 +1118,9 @@ ZEND_API int zend_gc_collect_cycles(void) if (obj->handlers->dtor_obj && (obj->handlers->dtor_obj != zend_objects_destroy_object || obj->ce->destructor)) { - GC_REFCOUNT(obj)++; + GC_ADDREF(obj); obj->handlers->dtor_obj(obj); - GC_REFCOUNT(obj)--; + GC_DELREF(obj); } } } @@ -1154,9 +1154,9 @@ ZEND_API int zend_gc_collect_cycles(void) if (!(GC_FLAGS(obj) & IS_OBJ_FREE_CALLED)) { GC_FLAGS(obj) |= IS_OBJ_FREE_CALLED; if (obj->handlers->free_obj) { - GC_REFCOUNT(obj)++; + GC_ADDREF(obj); obj->handlers->free_obj(obj); - GC_REFCOUNT(obj)--; + GC_DELREF(obj); } } SET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[obj->handle], EG(objects_store).free_list_head); diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index ce7f4374cf..c75f86ac2f 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -514,7 +514,7 @@ static void zend_generator_add_child(zend_generator *generator, zend_generator * if (was_leaf) { zend_generator *next = generator->node.parent; leaf->node.ptr.root = generator->node.ptr.root; - ++GC_REFCOUNT(&generator->std); /* we need to increment the generator refcount here as it became integrated into the tree (no leaf), but we must not increment the refcount of the *whole* path in tree */ + GC_ADDREF(&generator->std); /* we need to increment the generator refcount here as it became integrated into the tree (no leaf), but we must not increment the refcount of the *whole* path in tree */ generator->node.ptr.leaf = leaf; while (next) { @@ -592,7 +592,7 @@ void zend_generator_yield_from(zend_generator *generator, zend_generator *from) generator->node.parent = from; zend_generator_get_current(generator); - --GC_REFCOUNT(&from->std); + GC_DELREF(&from->std); } ZEND_API zend_generator *zend_generator_update_current(zend_generator *generator, zend_generator *leaf) @@ -658,7 +658,7 @@ ZEND_API zend_generator *zend_generator_update_current(zend_generator *generator } else { do { root = root->node.parent; - ++GC_REFCOUNT(&root->std); + GC_ADDREF(&root->std); } while (root->node.parent); } } @@ -1014,14 +1014,14 @@ ZEND_METHOD(Generator, send) * Throws an exception into the generator */ ZEND_METHOD(Generator, throw) { - zval *exception, exception_copy; + zval *exception; zend_generator *generator; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_ZVAL(exception) ZEND_PARSE_PARAMETERS_END(); - ZVAL_DUP(&exception_copy, exception); + Z_TRY_ADDREF_P(exception); generator = (zend_generator *) Z_OBJ_P(getThis()); @@ -1030,7 +1030,7 @@ ZEND_METHOD(Generator, throw) if (generator->execute_data) { zend_generator *root = zend_generator_get_current(generator); - zend_generator_throw_exception(root, &exception_copy); + zend_generator_throw_exception(root, exception); zend_generator_resume(generator); @@ -1044,7 +1044,7 @@ ZEND_METHOD(Generator, throw) } else { /* If the generator is already closed throw the exception in the * current context */ - zend_throw_exception_object(&exception_copy); + zend_throw_exception_object(exception); } } /* }}} */ @@ -1165,7 +1165,7 @@ static void zend_generator_iterator_rewind(zend_object_iterator *iterator) /* {{ } /* }}} */ -static zend_object_iterator_funcs zend_generator_iterator_functions = { +static const zend_object_iterator_funcs zend_generator_iterator_functions = { zend_generator_iterator_dtor, zend_generator_iterator_valid, zend_generator_iterator_get_data, diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index d9e872ae0e..5555a3863b 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -155,6 +155,7 @@ struct _zend_executor_globals { zval *vm_stack_top; zval *vm_stack_end; zend_vm_stack vm_stack; + size_t vm_stack_page_size; struct _zend_execute_data *current_execute_data; zend_class_entry *fake_scope; /* used to avoid checks accessing properties */ diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index c1ac05cc3d..29be2ca186 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -72,19 +72,6 @@ static void _zend_is_inconsistent(const HashTable *ht, const char *file, int lin #define SET_INCONSISTENT(n) #endif -#define HASH_PROTECT_RECURSION(ht) \ - if ((ht)->u.flags & HASH_FLAG_APPLY_PROTECTION) { \ - if (((ht)->u.flags & ZEND_HASH_APPLY_COUNT_MASK) >= (3 << 8)) { \ - zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?");\ - } \ - ZEND_HASH_INC_APPLY_COUNT(ht); \ - } - -#define HASH_UNPROTECT_RECURSION(ht) \ - if ((ht)->u.flags & HASH_FLAG_APPLY_PROTECTION) { \ - ZEND_HASH_DEC_APPLY_COUNT(ht); \ - } - #define ZEND_HASH_IF_FULL_DO_RESIZE(ht) \ if ((ht)->nNumUsed >= (ht)->nTableSize) { \ zend_hash_do_resize(ht); \ @@ -132,12 +119,12 @@ static zend_always_inline void zend_hash_real_init_ex(HashTable *ht, int packed) HT_ASSERT_RC1(ht); ZEND_ASSERT(!((ht)->u.flags & HASH_FLAG_INITIALIZED)); if (packed) { - HT_SET_DATA_ADDR(ht, pemalloc(HT_SIZE(ht), (ht)->u.flags & HASH_FLAG_PERSISTENT)); + HT_SET_DATA_ADDR(ht, pemalloc(HT_SIZE(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT)); (ht)->u.flags |= HASH_FLAG_INITIALIZED | HASH_FLAG_PACKED; HT_HASH_RESET_PACKED(ht); } else { (ht)->nTableMask = -(ht)->nTableSize; - HT_SET_DATA_ADDR(ht, pemalloc(HT_SIZE(ht), (ht)->u.flags & HASH_FLAG_PERSISTENT)); + HT_SET_DATA_ADDR(ht, pemalloc(HT_SIZE(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT)); (ht)->u.flags |= HASH_FLAG_INITIALIZED; if (EXPECTED(ht->nTableMask == (uint32_t)-8)) { Bucket *arData = ht->arData; @@ -170,11 +157,25 @@ static zend_always_inline void zend_hash_check_init(HashTable *ht, int packed) static const uint32_t uninitialized_bucket[-HT_MIN_MASK] = {HT_INVALID_IDX, HT_INVALID_IDX}; -ZEND_API void ZEND_FASTCALL _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC) -{ - GC_REFCOUNT(ht) = 1; - GC_TYPE_INFO(ht) = IS_ARRAY | (persistent ? 0 : (GC_COLLECTABLE << GC_FLAGS_SHIFT)); - ht->u.flags = (persistent ? HASH_FLAG_PERSISTENT : 0) | HASH_FLAG_APPLY_PROTECTION | HASH_FLAG_STATIC_KEYS; +ZEND_API const HashTable zend_empty_array = { + .gc.refcount = 2, + .gc.u.type_info = IS_ARRAY | (GC_IMMUTABLE << GC_FLAGS_SHIFT), + .u.flags = HASH_FLAG_STATIC_KEYS, + .nTableMask = HT_MIN_MASK, + .arData = (Bucket*)&uninitialized_bucket[2], + .nNumUsed = 0, + .nNumOfElements = 0, + .nTableSize = HT_MIN_SIZE, + .nInternalPointer = HT_INVALID_IDX, + .nNextFreeElement = 0, + .pDestructor = ZVAL_PTR_DTOR +}; + +static zend_always_inline void _zend_hash_init_int(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent) +{ + GC_SET_REFCOUNT(ht, 1); + GC_TYPE_INFO(ht) = IS_ARRAY | (persistent ? (GC_PERSISTENT << GC_FLAGS_SHIFT) : (GC_COLLECTABLE << GC_FLAGS_SHIFT)); + ht->u.flags = HASH_FLAG_STATIC_KEYS; ht->nTableMask = HT_MIN_MASK; HT_SET_DATA_ADDR(ht, &uninitialized_bucket); ht->nNumUsed = 0; @@ -185,6 +186,18 @@ ZEND_API void ZEND_FASTCALL _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_ ht->nTableSize = zend_hash_check_size(nSize); } +ZEND_API void ZEND_FASTCALL _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent) +{ + _zend_hash_init_int(ht, nSize, pDestructor, persistent); +} + +ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t nSize ZEND_FILE_LINE_DC) +{ + HashTable *ht = emalloc(sizeof(HashTable)); + _zend_hash_init_int(ht, nSize, ZVAL_PTR_DTOR, 0); + return ht; +} + static void ZEND_FASTCALL zend_hash_packed_grow(HashTable *ht) { HT_ASSERT_RC1(ht); @@ -192,7 +205,7 @@ static void ZEND_FASTCALL zend_hash_packed_grow(HashTable *ht) zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket)); } ht->nTableSize += ht->nTableSize; - HT_SET_DATA_ADDR(ht, perealloc2(HT_GET_DATA_ADDR(ht), HT_SIZE(ht), HT_USED_SIZE(ht), ht->u.flags & HASH_FLAG_PERSISTENT)); + HT_SET_DATA_ADDR(ht, perealloc2(HT_GET_DATA_ADDR(ht), HT_SIZE(ht), HT_USED_SIZE(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT)); } ZEND_API void ZEND_FASTCALL zend_hash_real_init(HashTable *ht, zend_bool packed) @@ -210,11 +223,11 @@ ZEND_API void ZEND_FASTCALL zend_hash_packed_to_hash(HashTable *ht) HT_ASSERT_RC1(ht); ht->u.flags &= ~HASH_FLAG_PACKED; - new_data = pemalloc(HT_SIZE_EX(ht->nTableSize, -ht->nTableSize), (ht)->u.flags & HASH_FLAG_PERSISTENT); + new_data = pemalloc(HT_SIZE_EX(ht->nTableSize, -ht->nTableSize), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); ht->nTableMask = -ht->nTableSize; HT_SET_DATA_ADDR(ht, new_data); memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed); - pefree(old_data, (ht)->u.flags & HASH_FLAG_PERSISTENT); + pefree(old_data, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); zend_hash_rehash(ht); } @@ -224,21 +237,13 @@ ZEND_API void ZEND_FASTCALL zend_hash_to_packed(HashTable *ht) Bucket *old_buckets = ht->arData; HT_ASSERT_RC1(ht); - new_data = pemalloc(HT_SIZE_EX(ht->nTableSize, HT_MIN_MASK), (ht)->u.flags & HASH_FLAG_PERSISTENT); + new_data = pemalloc(HT_SIZE_EX(ht->nTableSize, HT_MIN_MASK), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); ht->u.flags |= HASH_FLAG_PACKED | HASH_FLAG_STATIC_KEYS; ht->nTableMask = HT_MIN_MASK; HT_SET_DATA_ADDR(ht, new_data); HT_HASH_RESET_PACKED(ht); memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed); - pefree(old_data, (ht)->u.flags & HASH_FLAG_PERSISTENT); -} - -ZEND_API void ZEND_FASTCALL _zend_hash_init_ex(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC) -{ - _zend_hash_init(ht, nSize, pDestructor, persistent ZEND_FILE_LINE_RELAY_CC); - if (!bApplyProtection) { - ht->u.flags &= ~HASH_FLAG_APPLY_PROTECTION; - } + pefree(old_data, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); } ZEND_API void ZEND_FASTCALL zend_hash_extend(HashTable *ht, uint32_t nSize, zend_bool packed) @@ -255,7 +260,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_extend(HashTable *ht, uint32_t nSize, zend ZEND_ASSERT(ht->u.flags & HASH_FLAG_PACKED); if (nSize > ht->nTableSize) { ht->nTableSize = zend_hash_check_size(nSize); - HT_SET_DATA_ADDR(ht, perealloc2(HT_GET_DATA_ADDR(ht), HT_SIZE(ht), HT_USED_SIZE(ht), ht->u.flags & HASH_FLAG_PERSISTENT)); + HT_SET_DATA_ADDR(ht, perealloc2(HT_GET_DATA_ADDR(ht), HT_SIZE(ht), HT_USED_SIZE(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT)); } } else { ZEND_ASSERT(!(ht->u.flags & HASH_FLAG_PACKED)); @@ -263,12 +268,12 @@ ZEND_API void ZEND_FASTCALL zend_hash_extend(HashTable *ht, uint32_t nSize, zend void *new_data, *old_data = HT_GET_DATA_ADDR(ht); Bucket *old_buckets = ht->arData; nSize = zend_hash_check_size(nSize); - new_data = pemalloc(HT_SIZE_EX(nSize, -nSize), ht->u.flags & HASH_FLAG_PERSISTENT); + new_data = pemalloc(HT_SIZE_EX(nSize, -nSize), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); ht->nTableSize = nSize; ht->nTableMask = -ht->nTableSize; HT_SET_DATA_ADDR(ht, new_data); memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed); - pefree(old_data, ht->u.flags & HASH_FLAG_PERSISTENT); + pefree(old_data, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); zend_hash_rehash(ht); } } @@ -308,15 +313,6 @@ ZEND_API uint32_t zend_array_count(HashTable *ht) } /* }}} */ -ZEND_API void ZEND_FASTCALL zend_hash_set_apply_protection(HashTable *ht, zend_bool bApplyProtection) -{ - if (bApplyProtection) { - ht->u.flags |= HASH_FLAG_APPLY_PROTECTION; - } else { - ht->u.flags &= ~HASH_FLAG_APPLY_PROTECTION; - } -} - ZEND_API uint32_t ZEND_FASTCALL zend_hash_iterator_add(HashTable *ht, HashPosition pos) { HashTableIterator *iter = EG(ht_iterators); @@ -469,14 +465,18 @@ ZEND_API void ZEND_FASTCALL _zend_hash_iterators_update(HashTable *ht, HashPosit } } -static zend_always_inline Bucket *zend_hash_find_bucket(const HashTable *ht, zend_string *key) +static zend_always_inline Bucket *zend_hash_find_bucket(const HashTable *ht, zend_string *key, zend_bool known_hash) { zend_ulong h; uint32_t nIndex; uint32_t idx; Bucket *p, *arData; - h = zend_string_hash_val(key); + if (known_hash) { + h = ZSTR_H(key); + } else { + h = zend_string_hash_val(key); + } arData = ht->arData; nIndex = h | ht->nTableMask; idx = HT_HASH_EX(arData, nIndex); @@ -486,8 +486,7 @@ static zend_always_inline Bucket *zend_hash_find_bucket(const HashTable *ht, zen return p; } else if (EXPECTED(p->h == h) && EXPECTED(p->key) && - EXPECTED(ZSTR_LEN(p->key) == ZSTR_LEN(key)) && - EXPECTED(memcmp(ZSTR_VAL(p->key), ZSTR_VAL(key), ZSTR_LEN(key)) == 0)) { + EXPECTED(zend_string_equal_content(p->key, key))) { return p; } idx = Z_NEXT(p->val); @@ -550,11 +549,21 @@ static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_s if (UNEXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) { CHECK_INIT(ht, 0); + if (!ZSTR_IS_INTERNED(key)) { + zend_string_addref(key); + ht->u.flags &= ~HASH_FLAG_STATIC_KEYS; + zend_string_hash_val(key); + } goto add_to_hash; } else if (ht->u.flags & HASH_FLAG_PACKED) { zend_hash_packed_to_hash(ht); + if (!ZSTR_IS_INTERNED(key)) { + zend_string_addref(key); + ht->u.flags &= ~HASH_FLAG_STATIC_KEYS; + zend_string_hash_val(key); + } } else if ((flag & HASH_ADD_NEW) == 0) { - p = zend_hash_find_bucket(ht, key); + p = zend_hash_find_bucket(ht, key, 0); if (p) { zval *data; @@ -586,6 +595,14 @@ static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_s ZVAL_COPY_VALUE(data, pData); return data; } + if (!ZSTR_IS_INTERNED(key)) { + zend_string_addref(key); + ht->u.flags &= ~HASH_FLAG_STATIC_KEYS; + } + } else if (!ZSTR_IS_INTERNED(key)) { + zend_string_addref(key); + ht->u.flags &= ~HASH_FLAG_STATIC_KEYS; + zend_string_hash_val(key); } ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */ @@ -599,11 +616,6 @@ add_to_hash: zend_hash_iterators_update(ht, HT_INVALID_IDX, idx); p = ht->arData + idx; p->key = key; - if (!ZSTR_IS_INTERNED(key)) { - zend_string_addref(key); - ht->u.flags &= ~HASH_FLAG_STATIC_KEYS; - zend_string_hash_val(key); - } p->h = h = ZSTR_H(key); ZVAL_COPY_VALUE(&p->val, pData); nIndex = h | ht->nTableMask; @@ -613,6 +625,77 @@ add_to_hash: return &p->val; } +static zend_always_inline zval *_zend_hash_str_add_or_update_i(HashTable *ht, const char *str, size_t len, zend_ulong h, zval *pData, uint32_t flag ZEND_FILE_LINE_DC) +{ + zend_string *key; + uint32_t nIndex; + uint32_t idx; + Bucket *p; + + IS_CONSISTENT(ht); + HT_ASSERT_RC1(ht); + + if (UNEXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) { + CHECK_INIT(ht, 0); + goto add_to_hash; + } else if (ht->u.flags & HASH_FLAG_PACKED) { + zend_hash_packed_to_hash(ht); + } else if ((flag & HASH_ADD_NEW) == 0) { + p = zend_hash_str_find_bucket(ht, str, len, h); + + if (p) { + zval *data; + + if (flag & HASH_ADD) { + if (!(flag & HASH_UPDATE_INDIRECT)) { + return NULL; + } + ZEND_ASSERT(&p->val != pData); + data = &p->val; + if (Z_TYPE_P(data) == IS_INDIRECT) { + data = Z_INDIRECT_P(data); + if (Z_TYPE_P(data) != IS_UNDEF) { + return NULL; + } + } else { + return NULL; + } + } else { + ZEND_ASSERT(&p->val != pData); + data = &p->val; + if ((flag & HASH_UPDATE_INDIRECT) && Z_TYPE_P(data) == IS_INDIRECT) { + data = Z_INDIRECT_P(data); + } + } + if (ht->pDestructor) { + ht->pDestructor(data); + } + ZVAL_COPY_VALUE(data, pData); + return data; + } + } + + ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */ + +add_to_hash: + idx = ht->nNumUsed++; + ht->nNumOfElements++; + if (ht->nInternalPointer == HT_INVALID_IDX) { + ht->nInternalPointer = idx; + } + zend_hash_iterators_update(ht, HT_INVALID_IDX, idx); + p = ht->arData + idx; + p->key = key = zend_string_init(str, len, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); + p->h = ZSTR_H(key) = h; + ht->u.flags &= ~HASH_FLAG_STATIC_KEYS; + ZVAL_COPY_VALUE(&p->val, pData); + nIndex = h | ht->nTableMask; + Z_NEXT(p->val) = HT_HASH(ht, nIndex); + HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(idx); + + return &p->val; +} + ZEND_API zval* ZEND_FASTCALL _zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *pData, uint32_t flag ZEND_FILE_LINE_DC) { return _zend_hash_add_or_update_i(ht, key, pData, flag ZEND_FILE_LINE_RELAY_CC); @@ -640,42 +723,37 @@ ZEND_API zval* ZEND_FASTCALL _zend_hash_add_new(HashTable *ht, zend_string *key, ZEND_API zval* ZEND_FASTCALL _zend_hash_str_add_or_update(HashTable *ht, const char *str, size_t len, zval *pData, uint32_t flag ZEND_FILE_LINE_DC) { - zend_string *key = zend_string_init(str, len, ht->u.flags & HASH_FLAG_PERSISTENT); - zval *ret = _zend_hash_add_or_update_i(ht, key, pData, flag ZEND_FILE_LINE_RELAY_CC); - zend_string_release(key); - return ret; + zend_ulong h = zend_hash_func(str, len); + + return _zend_hash_str_add_or_update_i(ht, str, len, h, pData, flag ZEND_FILE_LINE_RELAY_CC); } ZEND_API zval* ZEND_FASTCALL _zend_hash_str_update(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC) { - zend_string *key = zend_string_init(str, len, ht->u.flags & HASH_FLAG_PERSISTENT); - zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_UPDATE ZEND_FILE_LINE_RELAY_CC); - zend_string_release(key); - return ret; + zend_ulong h = zend_hash_func(str, len); + + return _zend_hash_str_add_or_update_i(ht, str, len, h, pData, HASH_UPDATE ZEND_FILE_LINE_RELAY_CC); } ZEND_API zval* ZEND_FASTCALL _zend_hash_str_update_ind(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC) { - zend_string *key = zend_string_init(str, len, ht->u.flags & HASH_FLAG_PERSISTENT); - zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_UPDATE | HASH_UPDATE_INDIRECT ZEND_FILE_LINE_RELAY_CC); - zend_string_release(key); - return ret; + zend_ulong h = zend_hash_func(str, len); + + return _zend_hash_str_add_or_update_i(ht, str, len, h, pData, HASH_UPDATE | HASH_UPDATE_INDIRECT ZEND_FILE_LINE_RELAY_CC); } ZEND_API zval* ZEND_FASTCALL _zend_hash_str_add(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC) { - zend_string *key = zend_string_init(str, len, ht->u.flags & HASH_FLAG_PERSISTENT); - zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD ZEND_FILE_LINE_RELAY_CC); - zend_string_release(key); - return ret; + zend_ulong h = zend_hash_func(str, len); + + return _zend_hash_str_add_or_update_i(ht, str, len, h, pData, HASH_ADD ZEND_FILE_LINE_RELAY_CC); } ZEND_API zval* ZEND_FASTCALL _zend_hash_str_add_new(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC) { - zend_string *key = zend_string_init(str, len, ht->u.flags & HASH_FLAG_PERSISTENT); - zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD_NEW ZEND_FILE_LINE_RELAY_CC); - zend_string_delref(key); - return ret; + zend_ulong h = zend_hash_func(str, len); + + return _zend_hash_str_add_or_update_i(ht, str, len, h, pData, HASH_ADD_NEW ZEND_FILE_LINE_RELAY_CC); } ZEND_API zval* ZEND_FASTCALL zend_hash_index_add_empty_element(HashTable *ht, zend_ulong h) @@ -857,12 +935,12 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht) uint32_t nSize = ht->nTableSize + ht->nTableSize; Bucket *old_buckets = ht->arData; - new_data = pemalloc(HT_SIZE_EX(nSize, -nSize), ht->u.flags & HASH_FLAG_PERSISTENT); + new_data = pemalloc(HT_SIZE_EX(nSize, -nSize), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); ht->nTableSize = nSize; ht->nTableMask = -ht->nTableSize; HT_SET_DATA_ADDR(ht, new_data); memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed); - pefree(old_data, ht->u.flags & HASH_FLAG_PERSISTENT); + pefree(old_data, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); zend_hash_rehash(ht); } else { zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket)); @@ -1046,8 +1124,7 @@ ZEND_API int ZEND_FASTCALL zend_hash_del(HashTable *ht, zend_string *key) if ((p->key == key) || (p->h == h && p->key && - ZSTR_LEN(p->key) == ZSTR_LEN(key) && - memcmp(ZSTR_VAL(p->key), ZSTR_VAL(key), ZSTR_LEN(key)) == 0)) { + zend_string_equal_content(p->key, key))) { _zend_hash_del_el_ex(ht, idx, p, prev); return SUCCESS; } @@ -1077,8 +1154,7 @@ ZEND_API int ZEND_FASTCALL zend_hash_del_ind(HashTable *ht, zend_string *key) if ((p->key == key) || (p->h == h && p->key && - ZSTR_LEN(p->key) == ZSTR_LEN(key) && - memcmp(ZSTR_VAL(p->key), ZSTR_VAL(key), ZSTR_LEN(key)) == 0)) { + zend_string_equal_content(p->key, key))) { if (Z_TYPE(p->val) == IS_INDIRECT) { zval *data = Z_INDIRECT(p->val); @@ -1274,7 +1350,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht) } else if (EXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) { return; } - pefree(HT_GET_DATA_ADDR(ht), ht->u.flags & HASH_FLAG_PERSISTENT); + pefree(HT_GET_DATA_ADDR(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); } ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht) @@ -1452,7 +1528,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_graceful_destroy(HashTable *ht) _zend_hash_del_el(ht, HT_IDX_TO_HASH(idx), p); } if (ht->u.flags & HASH_FLAG_INITIALIZED) { - pefree(HT_GET_DATA_ADDR(ht), ht->u.flags & HASH_FLAG_PERSISTENT); + pefree(HT_GET_DATA_ADDR(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); } SET_INCONSISTENT(HT_DESTROYED); @@ -1476,7 +1552,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_graceful_reverse_destroy(HashTable *ht) } if (ht->u.flags & HASH_FLAG_INITIALIZED) { - pefree(HT_GET_DATA_ADDR(ht), ht->u.flags & HASH_FLAG_PERSISTENT); + pefree(HT_GET_DATA_ADDR(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); } SET_INCONSISTENT(HT_DESTROYED); @@ -1499,7 +1575,6 @@ ZEND_API void ZEND_FASTCALL zend_hash_apply(HashTable *ht, apply_func_t apply_fu IS_CONSISTENT(ht); - HASH_PROTECT_RECURSION(ht); for (idx = 0; idx < ht->nNumUsed; idx++) { p = ht->arData + idx; if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue; @@ -1513,7 +1588,6 @@ ZEND_API void ZEND_FASTCALL zend_hash_apply(HashTable *ht, apply_func_t apply_fu break; } } - HASH_UNPROTECT_RECURSION(ht); } @@ -1525,7 +1599,6 @@ ZEND_API void ZEND_FASTCALL zend_hash_apply_with_argument(HashTable *ht, apply_f IS_CONSISTENT(ht); - HASH_PROTECT_RECURSION(ht); for (idx = 0; idx < ht->nNumUsed; idx++) { p = ht->arData + idx; if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue; @@ -1539,11 +1612,10 @@ ZEND_API void ZEND_FASTCALL zend_hash_apply_with_argument(HashTable *ht, apply_f break; } } - HASH_UNPROTECT_RECURSION(ht); } -ZEND_API void ZEND_FASTCALL zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t apply_func, int num_args, ...) +ZEND_API void zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t apply_func, int num_args, ...) { uint32_t idx; Bucket *p; @@ -1553,8 +1625,6 @@ ZEND_API void ZEND_FASTCALL zend_hash_apply_with_arguments(HashTable *ht, apply_ IS_CONSISTENT(ht); - HASH_PROTECT_RECURSION(ht); - for (idx = 0; idx < ht->nNumUsed; idx++) { p = ht->arData + idx; if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue; @@ -1574,8 +1644,6 @@ ZEND_API void ZEND_FASTCALL zend_hash_apply_with_arguments(HashTable *ht, apply_ } va_end(args); } - - HASH_UNPROTECT_RECURSION(ht); } @@ -1587,7 +1655,6 @@ ZEND_API void ZEND_FASTCALL zend_hash_reverse_apply(HashTable *ht, apply_func_t IS_CONSISTENT(ht); - HASH_PROTECT_RECURSION(ht); idx = ht->nNumUsed; while (idx > 0) { idx--; @@ -1604,7 +1671,6 @@ ZEND_API void ZEND_FASTCALL zend_hash_reverse_apply(HashTable *ht, apply_func_t break; } } - HASH_UNPROTECT_RECURSION(ht); } @@ -1760,14 +1826,14 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source) IS_CONSISTENT(source); ALLOC_HASHTABLE(target); - GC_REFCOUNT(target) = 1; + GC_SET_REFCOUNT(target, 1); GC_TYPE_INFO(target) = IS_ARRAY | (GC_COLLECTABLE << GC_FLAGS_SHIFT); target->nTableSize = source->nTableSize; target->pDestructor = source->pDestructor; if (source->nNumUsed == 0) { - target->u.flags = (source->u.flags & ~(HASH_FLAG_INITIALIZED|HASH_FLAG_PACKED|HASH_FLAG_PERSISTENT|ZEND_HASH_APPLY_COUNT_MASK)) | HASH_FLAG_APPLY_PROTECTION | HASH_FLAG_STATIC_KEYS; + target->u.flags = (source->u.flags & ~(HASH_FLAG_INITIALIZED|HASH_FLAG_PACKED)) | HASH_FLAG_STATIC_KEYS; target->nTableMask = HT_MIN_MASK; target->nNumUsed = 0; target->nNumOfElements = 0; @@ -1775,7 +1841,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source) target->nInternalPointer = HT_INVALID_IDX; HT_SET_DATA_ADDR(target, &uninitialized_bucket); } else if (GC_FLAGS(source) & IS_ARRAY_IMMUTABLE) { - target->u.flags = (source->u.flags & ~HASH_FLAG_PERSISTENT) | HASH_FLAG_APPLY_PROTECTION; + target->u.flags = source->u.flags; target->nTableMask = source->nTableMask; target->nNumUsed = source->nNumUsed; target->nNumOfElements = source->nNumOfElements; @@ -1792,7 +1858,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source) target->nInternalPointer = idx; } } else if (source->u.flags & HASH_FLAG_PACKED) { - target->u.flags = (source->u.flags & ~(HASH_FLAG_PERSISTENT|ZEND_HASH_APPLY_COUNT_MASK)) | HASH_FLAG_APPLY_PROTECTION; + target->u.flags = source->u.flags; target->nTableMask = source->nTableMask; target->nNumUsed = source->nNumUsed; target->nNumOfElements = source->nNumOfElements; @@ -1815,7 +1881,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source) target->nInternalPointer = idx; } } else { - target->u.flags = (source->u.flags & ~(HASH_FLAG_PERSISTENT|ZEND_HASH_APPLY_COUNT_MASK)) | HASH_FLAG_APPLY_PROTECTION; + target->u.flags = source->u.flags; target->nTableMask = source->nTableMask; target->nNextFreeElement = source->nNextFreeElement; target->nInternalPointer = source->nInternalPointer; @@ -1954,7 +2020,17 @@ ZEND_API zval* ZEND_FASTCALL zend_hash_find(const HashTable *ht, zend_string *ke IS_CONSISTENT(ht); - p = zend_hash_find_bucket(ht, key); + p = zend_hash_find_bucket(ht, key, 0); + return p ? &p->val : NULL; +} + +ZEND_API zval* ZEND_FASTCALL _zend_hash_find_known_hash(const HashTable *ht, zend_string *key) +{ + Bucket *p; + + IS_CONSISTENT(ht); + + p = zend_hash_find_bucket(ht, key, 1); return p ? &p->val : NULL; } @@ -1976,7 +2052,7 @@ ZEND_API zend_bool ZEND_FASTCALL zend_hash_exists(const HashTable *ht, zend_stri IS_CONSISTENT(ht); - p = zend_hash_find_bucket(ht, key); + p = zend_hash_find_bucket(ht, key, 0); return p ? 1 : 0; } @@ -2294,12 +2370,12 @@ ZEND_API int ZEND_FASTCALL zend_hash_sort_ex(HashTable *ht, sort_func_t sort, co void *new_data, *old_data = HT_GET_DATA_ADDR(ht); Bucket *old_buckets = ht->arData; - new_data = pemalloc(HT_SIZE_EX(ht->nTableSize, HT_MIN_MASK), (ht->u.flags & HASH_FLAG_PERSISTENT)); + new_data = pemalloc(HT_SIZE_EX(ht->nTableSize, HT_MIN_MASK), (GC_FLAGS(ht) & IS_ARRAY_PERSISTENT)); ht->u.flags |= HASH_FLAG_PACKED | HASH_FLAG_STATIC_KEYS; ht->nTableMask = HT_MIN_MASK; HT_SET_DATA_ADDR(ht, new_data); memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed); - pefree(old_data, ht->u.flags & HASH_FLAG_PERSISTENT & HASH_FLAG_PERSISTENT); + pefree(old_data, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); HT_HASH_RESET_PACKED(ht); } else { zend_hash_rehash(ht); @@ -2393,11 +2469,25 @@ ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t co IS_CONSISTENT(ht1); IS_CONSISTENT(ht2); - HASH_PROTECT_RECURSION(ht1); - HASH_PROTECT_RECURSION(ht2); + if (ht1 == ht2) { + return 0; + } + + /* It's enough to protect only one of the arrays. + * The second one may be referenced from the first and this may cause + * false recursion detection. + */ + if (UNEXPECTED(GC_IS_RECURSIVE(ht1))) { + zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?"); + } + + if (!(GC_FLAGS(ht1) & GC_IMMUTABLE)) { + GC_PROTECT_RECURSION(ht1); + } result = zend_hash_compare_impl(ht1, ht2, compar, ordered); - HASH_UNPROTECT_RECURSION(ht1); - HASH_UNPROTECT_RECURSION(ht2); + if (!(GC_FLAGS(ht1) & GC_IMMUTABLE)) { + GC_UNPROTECT_RECURSION(ht1); + } return result; } @@ -2500,16 +2590,14 @@ ZEND_API HashTable* ZEND_FASTCALL zend_symtable_to_proptable(HashTable *ht) } ZEND_HASH_FOREACH_END(); if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_REFCOUNT(ht)++; + GC_ADDREF(ht); } return ht; convert: { - HashTable *new_ht = emalloc(sizeof(HashTable)); - - zend_hash_init(new_ht, zend_hash_num_elements(ht), NULL, ZVAL_PTR_DTOR, 0); + HashTable *new_ht = zend_new_array(zend_hash_num_elements(ht)); ZEND_HASH_FOREACH_KEY_VAL(ht, num_key, str_key, zv) { if (!str_key) { @@ -2560,16 +2648,14 @@ ZEND_API HashTable* ZEND_FASTCALL zend_proptable_to_symtable(HashTable *ht, zend } if (EXPECTED(!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(ht)++; + GC_ADDREF(ht); } return ht; convert: { - HashTable *new_ht = emalloc(sizeof(HashTable)); - - zend_hash_init(new_ht, zend_hash_num_elements(ht), NULL, ZVAL_PTR_DTOR, 0); + HashTable *new_ht = zend_new_array(zend_hash_num_elements(ht)); ZEND_HASH_FOREACH_KEY_VAL(ht, num_key, str_key, zv) { do { diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index fc91dfb8c9..c27f08bd72 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -35,8 +35,6 @@ #define HASH_ADD_NEW (1<<3) #define HASH_ADD_NEXT (1<<4) -#define HASH_FLAG_PERSISTENT (1<<0) -#define HASH_FLAG_APPLY_PROTECTION (1<<1) #define HASH_FLAG_PACKED (1<<2) #define HASH_FLAG_INITIALIZED (1<<3) #define HASH_FLAG_STATIC_KEYS (1<<4) /* long and interned strings */ @@ -58,6 +56,15 @@ # define HT_ALLOW_COW_VIOLATION(ht) #endif +extern ZEND_API const HashTable zend_empty_array; + +#define ZVAL_EMPTY_ARRAY(z) do { \ + zval *__z = (z); \ + Z_ARR_P(__z) = (zend_array*)&zend_empty_array; \ + Z_TYPE_INFO_P(__z) = IS_ARRAY | (IS_TYPE_COPYABLE << Z_TYPE_FLAGS_SHIFT); \ + } while (0) + + typedef struct _zend_hash_key { zend_ulong h; zend_string *key; @@ -68,12 +75,14 @@ typedef zend_bool (*merge_checker_func_t)(HashTable *target_ht, zval *source_dat BEGIN_EXTERN_C() /* startup/shutdown */ -ZEND_API void ZEND_FASTCALL _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC); -ZEND_API void ZEND_FASTCALL _zend_hash_init_ex(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC); +ZEND_API void ZEND_FASTCALL _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent); ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht); ZEND_API void ZEND_FASTCALL zend_hash_clean(HashTable *ht); -#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent) _zend_hash_init((ht), (nSize), (pDestructor), (persistent) ZEND_FILE_LINE_CC) -#define zend_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection) _zend_hash_init_ex((ht), (nSize), (pDestructor), (persistent), (bApplyProtection) ZEND_FILE_LINE_CC) + +#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent) \ + _zend_hash_init((ht), (nSize), (pDestructor), (persistent)) +#define zend_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection) \ + _zend_hash_init((ht), (nSize), (pDestructor), (persistent)) ZEND_API void ZEND_FASTCALL zend_hash_real_init(HashTable *ht, zend_bool packed); ZEND_API void ZEND_FASTCALL zend_hash_packed_to_hash(HashTable *ht); @@ -145,7 +154,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_graceful_destroy(HashTable *ht); ZEND_API void ZEND_FASTCALL zend_hash_graceful_reverse_destroy(HashTable *ht); ZEND_API void ZEND_FASTCALL zend_hash_apply(HashTable *ht, apply_func_t apply_func); ZEND_API void ZEND_FASTCALL zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t apply_func, void *); -ZEND_API void ZEND_FASTCALL zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t apply_func, int, ...); +ZEND_API void zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t apply_func, int, ...); /* This function should be used with special care (in other words, * it should usually not be used). When used with the ZEND_HASH_APPLY_STOP @@ -170,6 +179,18 @@ ZEND_API zval* ZEND_FASTCALL zend_hash_str_find(const HashTable *ht, const char ZEND_API zval* ZEND_FASTCALL zend_hash_index_find(const HashTable *ht, zend_ulong h); ZEND_API zval* ZEND_FASTCALL _zend_hash_index_find(const HashTable *ht, zend_ulong h); +/* The same as zend_hash_find(), but hash value of the key must be already calculated */ +ZEND_API zval* ZEND_FASTCALL _zend_hash_find_known_hash(const HashTable *ht, zend_string *key); + +static zend_always_inline zval *zend_hash_find_ex(const HashTable *ht, zend_string *key, zend_bool known_hash) +{ + if (known_hash) { + return _zend_hash_find_known_hash(ht, key); + } else { + return zend_hash_find(ht, key); + } +} + #define ZEND_HASH_INDEX_FIND(_ht, _h, _ret, _not_found) do { \ if (EXPECTED((_ht)->u.flags & HASH_FLAG_PACKED)) { \ if (EXPECTED((zend_ulong)(_h) < (zend_ulong)(_ht)->nNumUsed)) { \ @@ -250,6 +271,10 @@ ZEND_API zval* ZEND_FASTCALL zend_hash_minmax(const HashTable *ht, compare_func_ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht); +#define zend_new_array(size) \ + _zend_new_array(size ZEND_FILE_LINE_CC) + +ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t size ZEND_FILE_LINE_DC); ZEND_API uint32_t zend_array_count(HashTable *ht); ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source); ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht); @@ -317,6 +342,16 @@ static zend_always_inline zval *zend_hash_find_ind(const HashTable *ht, zend_str } +static zend_always_inline zval *zend_hash_find_ex_ind(const HashTable *ht, zend_string *key, zend_bool known_hash) +{ + zval *zv; + + zv = zend_hash_find_ex(ht, key, known_hash); + return (zv && Z_TYPE_P(zv) == IS_INDIRECT) ? + ((Z_TYPE_P(Z_INDIRECT_P(zv)) != IS_UNDEF) ? Z_INDIRECT_P(zv) : NULL) : zv; +} + + static zend_always_inline int zend_hash_exists_ind(const HashTable *ht, zend_string *key) { zval *zv; @@ -614,7 +649,20 @@ static zend_always_inline void *zend_hash_add_mem(HashTable *ht, zend_string *ke ZVAL_PTR(&tmp, NULL); if ((zv = zend_hash_add(ht, key, &tmp))) { - Z_PTR_P(zv) = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT); + Z_PTR_P(zv) = pemalloc(size, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); + memcpy(Z_PTR_P(zv), pData, size); + return Z_PTR_P(zv); + } + return NULL; +} + +static zend_always_inline void *zend_hash_add_new_mem(HashTable *ht, zend_string *key, void *pData, size_t size) +{ + zval tmp, *zv; + + ZVAL_PTR(&tmp, NULL); + if ((zv = zend_hash_add_new(ht, key, &tmp))) { + Z_PTR_P(zv) = pemalloc(size, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); memcpy(Z_PTR_P(zv), pData, size); return Z_PTR_P(zv); } @@ -627,7 +675,20 @@ static zend_always_inline void *zend_hash_str_add_mem(HashTable *ht, const char ZVAL_PTR(&tmp, NULL); if ((zv = zend_hash_str_add(ht, str, len, &tmp))) { - Z_PTR_P(zv) = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT); + Z_PTR_P(zv) = pemalloc(size, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); + memcpy(Z_PTR_P(zv), pData, size); + return Z_PTR_P(zv); + } + return NULL; +} + +static zend_always_inline void *zend_hash_str_add_new_mem(HashTable *ht, const char *str, size_t len, void *pData, size_t size) +{ + zval tmp, *zv; + + ZVAL_PTR(&tmp, NULL); + if ((zv = zend_hash_str_add_new(ht, str, len, &tmp))) { + Z_PTR_P(zv) = pemalloc(size, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); memcpy(Z_PTR_P(zv), pData, size); return Z_PTR_P(zv); } @@ -638,7 +699,7 @@ static zend_always_inline void *zend_hash_update_mem(HashTable *ht, zend_string { void *p; - p = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT); + p = pemalloc(size, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); memcpy(p, pData, size); return zend_hash_update_ptr(ht, key, p); } @@ -647,7 +708,7 @@ static zend_always_inline void *zend_hash_str_update_mem(HashTable *ht, const ch { void *p; - p = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT); + p = pemalloc(size, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); memcpy(p, pData, size); return zend_hash_str_update_ptr(ht, str, len, p); } @@ -690,7 +751,7 @@ static zend_always_inline void *zend_hash_index_add_mem(HashTable *ht, zend_ulon ZVAL_PTR(&tmp, NULL); if ((zv = zend_hash_index_add(ht, h, &tmp))) { - Z_PTR_P(zv) = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT); + Z_PTR_P(zv) = pemalloc(size, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); memcpy(Z_PTR_P(zv), pData, size); return Z_PTR_P(zv); } @@ -715,7 +776,7 @@ static zend_always_inline void *zend_hash_index_update_mem(HashTable *ht, zend_u { void *p; - p = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT); + p = pemalloc(size, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); memcpy(p, pData, size); return zend_hash_index_update_ptr(ht, h, p); } @@ -726,7 +787,7 @@ static zend_always_inline void *zend_hash_next_index_insert_mem(HashTable *ht, v ZVAL_PTR(&tmp, NULL); if ((zv = zend_hash_next_index_insert(ht, &tmp))) { - Z_PTR_P(zv) = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT); + Z_PTR_P(zv) = pemalloc(size, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); memcpy(Z_PTR_P(zv), pData, size); return Z_PTR_P(zv); } @@ -746,6 +807,19 @@ static zend_always_inline void *zend_hash_find_ptr(const HashTable *ht, zend_str } } +static zend_always_inline void *zend_hash_find_ex_ptr(const HashTable *ht, zend_string *key, zend_bool known_hash) +{ + zval *zv; + + zv = zend_hash_find_ex(ht, key, known_hash); + if (zv) { + ZEND_ASSUME(Z_PTR_P(zv)); + return Z_PTR_P(zv); + } else { + return NULL; + } +} + static zend_always_inline void *zend_hash_str_find_ptr(const HashTable *ht, const char *str, size_t len) { zval *zv; @@ -978,16 +1052,6 @@ static zend_always_inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht, _key = _p->key; \ _val = _z; -#define ZEND_HASH_APPLY_PROTECTION(ht) \ - ((ht)->u.flags & HASH_FLAG_APPLY_PROTECTION) - -#define ZEND_HASH_APPLY_SHIFT 8 -#define ZEND_HASH_APPLY_COUNT_MASK 0xff00 -#define ZEND_HASH_GET_APPLY_COUNT(ht) (((ht)->u.flags & ZEND_HASH_APPLY_COUNT_MASK) >> ZEND_HASH_APPLY_SHIFT) -#define ZEND_HASH_INC_APPLY_COUNT(ht) ((ht)->u.flags += (1 << ZEND_HASH_APPLY_SHIFT)) -#define ZEND_HASH_DEC_APPLY_COUNT(ht) ((ht)->u.flags -= (1 << ZEND_HASH_APPLY_SHIFT)) - - /* The following macros are useful to insert a sequence of new elements * of packed array. They may be use insted of series of * zend_hash_next_index_insert_new() diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 383df1a0f9..ef83622ba8 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -79,7 +79,7 @@ static zend_function *zend_duplicate_function(zend_function *func, zend_class_en return func; } if (!(GC_FLAGS(func->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) { - GC_REFCOUNT(func->op_array.static_variables)++; + GC_ADDREF(func->op_array.static_variables); } new_function = zend_arena_alloc(&CG(arena), sizeof(zend_op_array)); memcpy(new_function, func, sizeof(zend_op_array)); @@ -495,11 +495,9 @@ static ZEND_COLD zend_string *zend_get_function_declaration(const zend_function } } if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) { - zval *zv = RT_CONSTANT(&fptr->op_array, precv->op2); + zval *zv = RT_CONSTANT(precv, precv->op2); - if (Z_TYPE_P(zv) == IS_CONSTANT) { - smart_str_append(&str, Z_STR_P(zv)); - } else if (Z_TYPE_P(zv) == IS_FALSE) { + if (Z_TYPE_P(zv) == IS_FALSE) { smart_str_appends(&str, "false"); } else if (Z_TYPE_P(zv) == IS_TRUE) { smart_str_appends(&str, "true"); @@ -515,11 +513,17 @@ static ZEND_COLD zend_string *zend_get_function_declaration(const zend_function } else if (Z_TYPE_P(zv) == IS_ARRAY) { smart_str_appends(&str, "Array"); } else if (Z_TYPE_P(zv) == IS_CONSTANT_AST) { - smart_str_appends(&str, "<expression>"); + zend_ast *ast = Z_ASTVAL_P(zv); + if (ast->kind == ZEND_AST_CONSTANT) { + smart_str_append(&str, zend_ast_get_constant_name(ast)); + } else { + smart_str_appends(&str, "<expression>"); + } } else { - zend_string *zv_str = zval_get_string(zv); + zend_string *tmp_zv_str; + zend_string *zv_str = zval_get_tmp_string(zv, &tmp_zv_str); smart_str_append(&str, zv_str); - zend_string_release(zv_str); + zend_tmp_string_release(tmp_zv_str); } } } else { @@ -629,7 +633,7 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function * static zend_function *do_inherit_method(zend_string *key, zend_function *parent, zend_class_entry *ce) /* {{{ */ { - zval *child = zend_hash_find(&ce->function_table, key); + zval *child = zend_hash_find_ex(&ce->function_table, key, 1); if (child) { zend_function *func = (zend_function*)Z_PTR_P(child); @@ -659,7 +663,7 @@ static zend_function *do_inherit_method(zend_string *key, zend_function *parent, static void do_inherit_property(zend_property_info *parent_info, zend_string *key, zend_class_entry *ce) /* {{{ */ { - zval *child = zend_hash_find(&ce->properties_info, key); + zval *child = zend_hash_find_ex(&ce->properties_info, key, 1); zend_property_info *child_info; if (UNEXPECTED(child)) { @@ -761,27 +765,25 @@ ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_ static void do_inherit_class_constant(zend_string *name, zend_class_constant *parent_const, zend_class_entry *ce) /* {{{ */ { - zend_class_constant *c = zend_hash_find_ptr(&ce->constants_table, name); + zval *zv = zend_hash_find_ex(&ce->constants_table, name, 1); + zend_class_constant *c; - if (c != NULL) { + if (zv != NULL) { + c = (zend_class_constant*)Z_PTR_P(zv); if (UNEXPECTED((Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PPP_MASK) > (Z_ACCESS_FLAGS(parent_const->value) & ZEND_ACC_PPP_MASK))) { zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::%s must be %s (as in class %s)%s", ZSTR_VAL(ce->name), ZSTR_VAL(name), zend_visibility_string(Z_ACCESS_FLAGS(parent_const->value)), ZSTR_VAL(ce->parent->name), (Z_ACCESS_FLAGS(parent_const->value) & ZEND_ACC_PUBLIC) ? "" : " or weaker"); } } else if (!(Z_ACCESS_FLAGS(parent_const->value) & ZEND_ACC_PRIVATE)) { - if (Z_CONSTANT(parent_const->value)) { + if (Z_TYPE(parent_const->value) == IS_CONSTANT_AST) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } if (ce->type & ZEND_INTERNAL_CLASS) { - if (Z_REFCOUNTED(parent_const->value)) { - Z_ADDREF(parent_const->value); - } c = pemalloc(sizeof(zend_class_constant), 1); memcpy(c, parent_const, sizeof(zend_class_constant)); - } else { - c = parent_const; + parent_const = c; } - _zend_hash_append_ptr(&ce->constants_table, name, c); + _zend_hash_append_ptr(&ce->constants_table, name, parent_const); } } /* }}} */ @@ -839,24 +841,28 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent ce->default_properties_table = end; } src = parent_ce->default_properties_table + parent_ce->default_properties_count; - do { - dst--; - src--; -#ifdef ZTS - if (parent_ce->type != ce->type) { - ZVAL_DUP(dst, src); - if (Z_OPT_CONSTANT_P(dst)) { + if (UNEXPECTED(parent_ce->type != ce->type)) { + /* User class extends internal */ + do { + dst--; + src--; + ZVAL_COPY_OR_DUP(dst, src); + if (Z_OPT_TYPE_P(dst) == IS_CONSTANT_AST) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } continue; - } -#endif - - ZVAL_COPY(dst, src); - if (Z_OPT_CONSTANT_P(dst)) { - ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; - } - } while (dst != end); + } while (dst != end); + } else { + do { + dst--; + src--; + ZVAL_COPY(dst, src); + if (Z_OPT_TYPE_P(dst) == IS_CONSTANT_AST) { + ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; + } + continue; + } while (dst != end); + } ce->default_properties_count += parent_ce->default_properties_count; } @@ -881,23 +887,43 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent dst = end + parent_ce->default_static_members_count; ce->default_static_members_table = end; } - src = parent_ce->default_static_members_table + parent_ce->default_static_members_count; - do { - dst--; - src--; - if (parent_ce->type == ZEND_INTERNAL_CLASS) { + if (UNEXPECTED(parent_ce->type != ce->type)) { + /* User class extends internal */ + if (UNEXPECTED(zend_update_class_constants(parent_ce) != SUCCESS)) { + ZEND_ASSERT(0); + } + src = CE_STATIC_MEMBERS(parent_ce) + parent_ce->default_static_members_count; + do { + dst--; + src--; + ZVAL_MAKE_REF(src); + ZVAL_COPY_VALUE(dst, src); + Z_ADDREF_P(dst); + } while (dst != end); + } else if (ce->type == ZEND_USER_CLASS) { + src = parent_ce->default_static_members_table + parent_ce->default_static_members_count; + do { + dst--; + src--; + ZVAL_MAKE_REF(src); + ZVAL_COPY_VALUE(dst, src); + Z_ADDREF_P(dst); + if (Z_TYPE_P(Z_REFVAL_P(dst)) == IS_CONSTANT_AST) { + ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; + } + } while (dst != end); + } else { + src = parent_ce->default_static_members_table + parent_ce->default_static_members_count; + do { + dst--; + src--; if (!Z_ISREF_P(src)) { ZVAL_NEW_PERSISTENT_REF(src, src); } - } else { - ZVAL_MAKE_REF(src); - } - ZVAL_COPY_VALUE(dst, src); - Z_ADDREF_P(dst); - if (Z_CONSTANT_P(Z_REFVAL_P(dst))) { - ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; - } - } while (dst != end); + ZVAL_COPY_VALUE(dst, src); + Z_ADDREF_P(dst); + } while (dst != end); + } ce->default_static_members_count += parent_ce->default_static_members_count; if (ce->type == ZEND_USER_CLASS) { ce->static_members_table = ce->default_static_members_table; @@ -966,9 +992,11 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent static zend_bool do_inherit_constant_check(HashTable *child_constants_table, zend_class_constant *parent_constant, zend_string *name, const zend_class_entry *iface) /* {{{ */ { + zval *zv = zend_hash_find_ex(child_constants_table, name, 1); zend_class_constant *old_constant; - if ((old_constant = zend_hash_find_ptr(child_constants_table, name)) != NULL) { + if (zv != NULL) { + old_constant = (zend_class_constant*)Z_PTR_P(zv); if (old_constant->ce != parent_constant->ce) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot inherit previously-inherited or override constant %s from interface %s", ZSTR_VAL(name), ZSTR_VAL(iface->name)); } @@ -982,19 +1010,15 @@ static void do_inherit_iface_constant(zend_string *name, zend_class_constant *c, { if (do_inherit_constant_check(&ce->constants_table, c, name, iface)) { zend_class_constant *ct; - if (Z_CONSTANT(c->value)) { + if (Z_TYPE(c->value) == IS_CONSTANT_AST) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } if (ce->type & ZEND_INTERNAL_CLASS) { - if (Z_REFCOUNTED(c->value)) { - Z_ADDREF(c->value); - } ct = pemalloc(sizeof(zend_class_constant), 1); memcpy(ct, c, sizeof(zend_class_constant)); - } else { - ct = c; + c = ct; } - zend_hash_update_ptr(&ce->constants_table, name, ct); + zend_hash_update_ptr(&ce->constants_table, name, c); } } /* }}} */ @@ -1145,6 +1169,11 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s zend_function *new_fn; if ((existing_fn = zend_hash_find_ptr(&ce->function_table, key)) != NULL) { + /* if it is the same function regardless of where it is coming from, there is no conflict and we do not need to add it again */ + if (existing_fn->op_array.opcodes == fn->op_array.opcodes) { + return; + } + if (existing_fn->common.scope == ce) { /* members from the current class override trait methods */ /* use temporary *overriden HashTable to detect hidden conflict */ @@ -1565,10 +1594,14 @@ static void zend_do_traits_property_binding(zend_class_entry *ce) /* {{{ */ zend_hash_del(&ce->properties_info, prop_name); flags |= ZEND_ACC_CHANGED; } else { + not_compatible = 1; + if ((coliding_prop->flags & (ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC)) == (flags & (ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC))) { - /* flags are identical, now the value needs to be checked */ + /* the flags are identical, thus, the properties may be compatible */ zval *op1, *op2; + zval op1_tmp, op2_tmp; + if (flags & ZEND_ACC_STATIC) { op1 = &ce->default_static_members_table[coliding_prop->offset]; op2 = &ce->traits[i]->default_static_members_table[property_info->offset]; @@ -1578,10 +1611,27 @@ static void zend_do_traits_property_binding(zend_class_entry *ce) /* {{{ */ op1 = &ce->default_properties_table[OBJ_PROP_TO_NUM(coliding_prop->offset)]; op2 = &ce->traits[i]->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)]; } + + /* if any of the values is a constant, we try to resolve it */ + if (UNEXPECTED(Z_TYPE_P(op1) == IS_CONSTANT_AST)) { + ZVAL_COPY_OR_DUP(&op1_tmp, op1); + zval_update_constant_ex(&op1_tmp, ce); + op1 = &op1_tmp; + } + if (UNEXPECTED(Z_TYPE_P(op2) == IS_CONSTANT_AST)) { + ZVAL_COPY_OR_DUP(&op2_tmp, op2); + zval_update_constant_ex(&op2_tmp, ce); + op2 = &op2_tmp; + } + not_compatible = fast_is_not_identical_function(op1, op2); - } else { - /* the flags are not identical, thus, we assume properties are not compatible */ - not_compatible = 1; + + if (op1 == &op1_tmp) { + zval_ptr_dtor_nogc(&op1_tmp); + } + if (op2 == &op2_tmp) { + zval_ptr_dtor_nogc(&op2_tmp); + } } if (not_compatible) { @@ -1604,8 +1654,8 @@ static void zend_do_traits_property_binding(zend_class_entry *ce) /* {{{ */ } else { prop_value = &ce->traits[i]->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)]; } - if (Z_REFCOUNTED_P(prop_value)) Z_ADDREF_P(prop_value); + Z_TRY_ADDREF_P(prop_value); doc_comment = property_info->doc_comment ? zend_string_copy(property_info->doc_comment) : NULL; zend_declare_property_ex(ce, prop_name, prop_value, flags, @@ -1669,7 +1719,7 @@ static void zend_do_check_for_inconsistent_traits_aliasing(zend_class_entry *ce) ZEND_API void zend_do_bind_traits(zend_class_entry *ce) /* {{{ */ { - if (ce->num_traits <= 0) { + if (ce->num_traits == 0) { return; } diff --git a/Zend/zend_ini.c b/Zend/zend_ini.c index 54ee149222..cb711cbaeb 100644 --- a/Zend/zend_ini.c +++ b/Zend/zend_ini.c @@ -157,13 +157,13 @@ static void copy_ini_entry(zval *zv) /* {{{ */ Z_PTR_P(zv) = new_entry; memcpy(new_entry, old_entry, sizeof(zend_ini_entry)); if (old_entry->name) { - new_entry->name = zend_string_init(ZSTR_VAL(old_entry->name), ZSTR_LEN(old_entry->name), 1); + new_entry->name = zend_string_dup(old_entry->name, 1); } if (old_entry->value) { - new_entry->value = zend_string_init(ZSTR_VAL(old_entry->value), ZSTR_LEN(old_entry->value), 1); + new_entry->value = zend_string_dup(old_entry->value, 1); } if (old_entry->orig_value) { - new_entry->orig_value = zend_string_init(ZSTR_VAL(old_entry->orig_value), ZSTR_LEN(old_entry->orig_value), 1); + new_entry->orig_value = zend_string_dup(old_entry->orig_value, 1); } } /* }}} */ @@ -189,7 +189,12 @@ static int ini_key_compare(const void *a, const void *b) /* {{{ */ s = (const Bucket *) b; if (!f->key && !s->key) { /* both numeric */ - return ZEND_NORMALIZE_BOOL(f->h - s->h); + if (f->h > s->h) { + return -1; + } else if (f->h < s->h) { + return 1; + } + return 0; } else if (!f->key) { /* f is numeric, s is not */ return -1; } else if (!s->key) { /* s is numeric, f is not */ @@ -231,7 +236,7 @@ ZEND_API int zend_register_ini_entries(const zend_ini_entry_def *ini_entry, int while (ini_entry->name) { p = pemalloc(sizeof(zend_ini_entry), 1); - p->name = zend_string_init(ini_entry->name, ini_entry->name_length, 1); + p->name = zend_string_init_interned(ini_entry->name, ini_entry->name_length, 1); p->on_modify = ini_entry->on_modify; p->mh_arg1 = ini_entry->mh_arg1; p->mh_arg2 = ini_entry->mh_arg2; @@ -255,10 +260,10 @@ ZEND_API int zend_register_ini_entries(const zend_ini_entry_def *ini_entry, int if (((default_value = zend_get_configuration_directive(p->name)) != NULL) && (!p->on_modify || p->on_modify(p, Z_STR_P(default_value), p->mh_arg1, p->mh_arg2, p->mh_arg3, ZEND_INI_STAGE_STARTUP) == SUCCESS)) { - p->value = zend_string_copy(Z_STR_P(default_value)); + p->value = zend_new_interned_string(zend_string_copy(Z_STR_P(default_value))); } else { p->value = ini_entry->value ? - zend_string_init(ini_entry->value, ini_entry->value_length, 1) : NULL; + zend_string_init_interned(ini_entry->value, ini_entry->value_length, 1) : NULL; if (p->on_modify) { p->on_modify(p, p->value, p->mh_arg1, p->mh_arg2, p->mh_arg3, ZEND_INI_STAGE_STARTUP); @@ -308,7 +313,7 @@ ZEND_API int zend_alter_ini_entry_chars(zend_string *name, const char *value, si int ret; zend_string *new_value; - new_value = zend_string_init(value, value_length, stage != ZEND_INI_STAGE_RUNTIME); + new_value = zend_string_init(value, value_length, !(stage & ZEND_INI_STAGE_IN_REQUEST)); ret = zend_alter_ini_entry_ex(name, new_value, modify_type, stage, 0); zend_string_release(new_value); return ret; @@ -320,7 +325,7 @@ ZEND_API int zend_alter_ini_entry_chars_ex(zend_string *name, const char *value, int ret; zend_string *new_value; - new_value = zend_string_init(value, value_length, stage != ZEND_INI_STAGE_RUNTIME); + new_value = zend_string_init(value, value_length, !(stage & ZEND_INI_STAGE_IN_REQUEST)); ret = zend_alter_ini_entry_ex(name, new_value, modify_type, stage, force_change); zend_string_release(new_value); return ret; @@ -418,7 +423,7 @@ ZEND_API int zend_ini_register_displayer(char *name, uint32_t name_length, void * Data retrieval */ -ZEND_API zend_long zend_ini_long(char *name, uint32_t name_length, int orig) /* {{{ */ +ZEND_API zend_long zend_ini_long(char *name, size_t name_length, int orig) /* {{{ */ { zend_ini_entry *ini_entry; @@ -435,7 +440,7 @@ ZEND_API zend_long zend_ini_long(char *name, uint32_t name_length, int orig) /* } /* }}} */ -ZEND_API double zend_ini_double(char *name, uint32_t name_length, int orig) /* {{{ */ +ZEND_API double zend_ini_double(char *name, size_t name_length, int orig) /* {{{ */ { zend_ini_entry *ini_entry; @@ -452,7 +457,7 @@ ZEND_API double zend_ini_double(char *name, uint32_t name_length, int orig) /* { } /* }}} */ -ZEND_API char *zend_ini_string_ex(char *name, uint32_t name_length, int orig, zend_bool *exists) /* {{{ */ +ZEND_API char *zend_ini_string_ex(char *name, size_t name_length, int orig, zend_bool *exists) /* {{{ */ { zend_ini_entry *ini_entry; @@ -476,7 +481,7 @@ ZEND_API char *zend_ini_string_ex(char *name, uint32_t name_length, int orig, ze } /* }}} */ -ZEND_API char *zend_ini_string(char *name, uint32_t name_length, int orig) /* {{{ */ +ZEND_API char *zend_ini_string(char *name, size_t name_length, int orig) /* {{{ */ { zend_bool exists = 1; char *return_value; @@ -491,6 +496,19 @@ ZEND_API char *zend_ini_string(char *name, uint32_t name_length, int orig) /* {{ } /* }}} */ +ZEND_API zend_string *zend_ini_get_value(zend_string *name) /* {{{ */ +{ + zend_ini_entry *ini_entry; + + ini_entry = zend_hash_find_ptr(EG(ini_directives), name); + if (ini_entry) { + return ini_entry->value ? ini_entry->value : ZSTR_EMPTY_ALLOC(); + } else { + return NULL; + } +} +/* }}} */ + #if TONY_20070307 static void zend_ini_displayer_cb(zend_ini_entry *ini_entry, int type) /* {{{ */ { @@ -658,7 +676,7 @@ ZEND_API ZEND_INI_MH(OnUpdateLong) /* {{{ */ p = (zend_long *) (base+(size_t) mh_arg1); - *p = zend_atol(ZSTR_VAL(new_value), (int)ZSTR_LEN(new_value)); + *p = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value)); return SUCCESS; } /* }}} */ @@ -674,7 +692,7 @@ ZEND_API ZEND_INI_MH(OnUpdateLongGEZero) /* {{{ */ base = (char *) ts_resource(*((int *) mh_arg2)); #endif - tmp = zend_atol(ZSTR_VAL(new_value), (int)ZSTR_LEN(new_value)); + tmp = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value)); if (tmp < 0) { return FAILURE; } diff --git a/Zend/zend_ini.h b/Zend/zend_ini.h index 41d38adcef..cfea8da3fb 100644 --- a/Zend/zend_ini.h +++ b/Zend/zend_ini.h @@ -38,10 +38,10 @@ typedef struct _zend_ini_entry_def { void *mh_arg3; const char *value; void (*displayer)(zend_ini_entry *ini_entry, int type); - int modifiable; - uint32_t name_length; uint32_t value_length; + uint16_t name_length; + uint8_t modifiable; } zend_ini_entry_def; struct _zend_ini_entry { @@ -53,11 +53,13 @@ struct _zend_ini_entry { zend_string *value; zend_string *orig_value; void (*displayer)(zend_ini_entry *ini_entry, int type); - int modifiable; - int orig_modifiable; - int modified; int module_number; + + uint8_t modifiable; + uint8_t orig_modifiable; + uint8_t modified; + }; BEGIN_EXTERN_C() @@ -81,10 +83,11 @@ ZEND_API int zend_alter_ini_entry_chars_ex(zend_string *name, const char *value, ZEND_API int zend_restore_ini_entry(zend_string *name, int stage); ZEND_API void display_ini_entries(zend_module_entry *module); -ZEND_API zend_long zend_ini_long(char *name, uint32_t name_length, int orig); -ZEND_API double zend_ini_double(char *name, uint32_t name_length, int orig); -ZEND_API char *zend_ini_string(char *name, uint32_t name_length, int orig); -ZEND_API char *zend_ini_string_ex(char *name, uint32_t name_length, int orig, zend_bool *exists); +ZEND_API zend_long zend_ini_long(char *name, size_t name_length, int orig); +ZEND_API double zend_ini_double(char *name, size_t name_length, int orig); +ZEND_API char *zend_ini_string(char *name, size_t name_length, int orig); +ZEND_API char *zend_ini_string_ex(char *name, size_t name_length, int orig, zend_bool *exists); +ZEND_API zend_string *zend_ini_get_value(zend_string *name); ZEND_API int zend_ini_register_displayer(char *name, uint32_t name_length, void (*displayer)(zend_ini_entry *ini_entry, int type)); @@ -97,7 +100,7 @@ END_EXTERN_C() #define ZEND_INI_END() { NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0} }; #define ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, arg1, arg2, arg3, displayer) \ - { name, on_modify, arg1, arg2, arg3, default_value, displayer, modifiable, sizeof(name)-1, sizeof(default_value)-1 }, + { name, on_modify, arg1, arg2, arg3, default_value, displayer, sizeof(default_value)-1, sizeof(name)-1, modifiable }, #define ZEND_INI_ENTRY3(name, default_value, modifiable, on_modify, arg1, arg2, arg3) \ ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, arg1, arg2, arg3, NULL) @@ -173,6 +176,8 @@ END_EXTERN_C() #define ZEND_INI_STAGE_RUNTIME (1<<4) #define ZEND_INI_STAGE_HTACCESS (1<<5) +#define ZEND_INI_STAGE_IN_REQUEST (ZEND_INI_STAGE_ACTIVATE|ZEND_INI_STAGE_DEACTIVATE|ZEND_INI_STAGE_RUNTIME|ZEND_INI_STAGE_HTACCESS) + /* INI parsing engine */ typedef void (*zend_ini_parser_cb_t)(zval *arg1, zval *arg2, zval *arg3, int callback_type, void *arg); BEGIN_EXTERN_C() diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y index 82997e7f02..afca5538de 100644 --- a/Zend/zend_ini_parser.y +++ b/Zend/zend_ini_parser.y @@ -111,13 +111,14 @@ static void zend_ini_add_string(zval *result, zval *op1, zval *op2) int length, op1_len; if (Z_TYPE_P(op1) != IS_STRING) { - zend_string *str = zval_get_string(op1); /* ZEND_ASSERT(!Z_REFCOUNTED_P(op1)); */ if (ZEND_SYSTEM_INI) { + zend_string *tmp_str; + zend_string *str = zval_get_tmp_string(op1, &tmp_str); ZVAL_PSTRINGL(op1, ZSTR_VAL(str), ZSTR_LEN(str)); - zend_string_release(str); + zend_tmp_string_release(tmp_str); } else { - ZVAL_STR(op1, str); + ZVAL_STR(op1, zval_get_string_func(op1)); } } op1_len = (int)Z_STRLEN_P(op1); diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index 7a6484c2ba..430e3b9715 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -224,7 +224,7 @@ ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter) } /* }}} */ -zend_object_iterator_funcs zend_interface_iterator_funcs_iterator = { +static const zend_object_iterator_funcs zend_interface_iterator_funcs_iterator = { zend_user_it_dtor, zend_user_it_valid, zend_user_it_get_current_data, @@ -479,12 +479,12 @@ static int zend_implement_countable(zend_class_entry *interface, zend_class_entr /* }}}*/ /* {{{ function tables */ -const zend_function_entry zend_funcs_aggregate[] = { +static const zend_function_entry zend_funcs_aggregate[] = { ZEND_ABSTRACT_ME(iterator, getIterator, NULL) ZEND_FE_END }; -const zend_function_entry zend_funcs_iterator[] = { +static const zend_function_entry zend_funcs_iterator[] = { ZEND_ABSTRACT_ME(iterator, current, NULL) ZEND_ABSTRACT_ME(iterator, next, NULL) ZEND_ABSTRACT_ME(iterator, key, NULL) @@ -493,7 +493,7 @@ const zend_function_entry zend_funcs_iterator[] = { ZEND_FE_END }; -const zend_function_entry *zend_funcs_traversable = NULL; +static const zend_function_entry *zend_funcs_traversable = NULL; ZEND_BEGIN_ARG_INFO_EX(arginfo_arrayaccess_offset, 0, 0, 1) ZEND_ARG_INFO(0, offset) @@ -508,7 +508,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_arrayaccess_offset_value, 0, 0, 2) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() -const zend_function_entry zend_funcs_arrayaccess[] = { +static const zend_function_entry zend_funcs_arrayaccess[] = { ZEND_ABSTRACT_ME(arrayaccess, offsetExists, arginfo_arrayaccess_offset) ZEND_ABSTRACT_ME(arrayaccess, offsetGet, arginfo_arrayaccess_offset_get) ZEND_ABSTRACT_ME(arrayaccess, offsetSet, arginfo_arrayaccess_offset_value) @@ -520,7 +520,7 @@ ZEND_BEGIN_ARG_INFO(arginfo_serializable_serialize, 0) ZEND_ARG_INFO(0, serialized) ZEND_END_ARG_INFO() -const zend_function_entry zend_funcs_serializable[] = { +static const zend_function_entry zend_funcs_serializable[] = { ZEND_ABSTRACT_ME(serializable, serialize, NULL) ZEND_FENTRY(unserialize, NULL, arginfo_serializable_serialize, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT|ZEND_ACC_CTOR) ZEND_FE_END @@ -529,7 +529,7 @@ const zend_function_entry zend_funcs_serializable[] = { ZEND_BEGIN_ARG_INFO(arginfo_countable_count, 0) ZEND_END_ARG_INFO() -const zend_function_entry zend_funcs_countable[] = { +static const zend_function_entry zend_funcs_countable[] = { ZEND_ABSTRACT_ME(Countable, count, arginfo_countable_count) ZEND_FE_END }; diff --git a/Zend/zend_iterators.c b/Zend/zend_iterators.c index efbd3d028c..d08de65e7c 100644 --- a/Zend/zend_iterators.c +++ b/Zend/zend_iterators.c @@ -81,7 +81,7 @@ ZEND_API void zend_iterator_init(zend_object_iterator *iter) ZEND_API void zend_iterator_dtor(zend_object_iterator *iter) { - if (--GC_REFCOUNT(&iter->std) > 0) { + if (GC_DELREF(&iter->std) > 0) { return; } diff --git a/Zend/zend_iterators.h b/Zend/zend_iterators.h index a6f7456d02..ec9822ca2e 100644 --- a/Zend/zend_iterators.h +++ b/Zend/zend_iterators.h @@ -57,12 +57,12 @@ typedef struct _zend_object_iterator_funcs { struct _zend_object_iterator { zend_object std; zval data; - zend_object_iterator_funcs *funcs; + const zend_object_iterator_funcs *funcs; zend_ulong index; /* private to fe_reset/fe_fetch opcodes */ }; typedef struct _zend_class_iterator_funcs { - zend_object_iterator_funcs *funcs; + const zend_object_iterator_funcs *funcs; union _zend_function *zf_new_iterator; union _zend_function *zf_valid; union _zend_function *zf_current; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 2c508a59fe..6d11afc8ba 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -439,7 +439,7 @@ statement: | T_ECHO echo_expr_list ';' { $$ = $2; } | T_INLINE_HTML { $$ = zend_ast_create(ZEND_AST_ECHO, $1); } | expr ';' { $$ = $1; } - | T_UNSET '(' unset_variables ')' ';' { $$ = $3; } + | T_UNSET '(' unset_variables possible_comma ')' ';' { $$ = $3; } | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement { $$ = zend_ast_create(ZEND_AST_FOREACH, $3, $5, NULL, $7); } | T_FOREACH '(' expr T_AS foreach_variable T_DOUBLE_ARROW foreach_variable ')' @@ -670,7 +670,7 @@ return_type: argument_list: '(' ')' { $$ = zend_ast_create_list(0, ZEND_AST_ARG_LIST); } - | '(' non_empty_argument_list ')' { $$ = $2; } + | '(' non_empty_argument_list possible_comma ')' { $$ = $2; } ; non_empty_argument_list: @@ -1260,7 +1260,7 @@ encaps_var_offset: internal_functions_in_yacc: - T_ISSET '(' isset_variables ')' { $$ = $3; } + T_ISSET '(' isset_variables possible_comma ')' { $$ = $3; } | T_EMPTY '(' expr ')' { $$ = zend_ast_create(ZEND_AST_EMPTY, $3); } | T_INCLUDE expr { $$ = zend_ast_create_ex(ZEND_AST_INCLUDE_OR_EVAL, ZEND_INCLUDE, $2); } diff --git a/Zend/zend_language_scanner.c b/Zend/zend_language_scanner.c index a70148b461..d149154522 100644 --- a/Zend/zend_language_scanner.c +++ b/Zend/zend_language_scanner.c @@ -650,9 +650,7 @@ zend_op_array *compile_filename(int type, zval *filename) zend_string *opened_path = NULL; if (Z_TYPE_P(filename) != IS_STRING) { - tmp = *filename; - zval_copy_ctor(&tmp); - convert_to_string(&tmp); + ZVAL_STR(&tmp, zval_get_string(filename)); filename = &tmp; } file_handle.filename = Z_STRVAL_P(filename); @@ -1108,7 +1106,7 @@ restart: SCNG(yy_text) = YYCURSOR; -#line 1112 "Zend/zend_language_scanner.c" +#line 1110 "Zend/zend_language_scanner.c" { YYCTYPE yych; unsigned int yyaccept = 0; @@ -1160,7 +1158,7 @@ yyc_INITIAL: yy4: YYDEBUG(4, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1803 "Zend/zend_language_scanner.l" +#line 1801 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -1205,7 +1203,7 @@ inline_char_handler: HANDLE_NEWLINES(yytext, yyleng); RETURN_TOKEN(T_INLINE_HTML); } -#line 1209 "Zend/zend_language_scanner.c" +#line 1207 "Zend/zend_language_scanner.c" yy5: YYDEBUG(5, *YYCURSOR); yych = *++YYCURSOR; @@ -1221,7 +1219,7 @@ yy5: yy7: YYDEBUG(7, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1794 "Zend/zend_language_scanner.l" +#line 1792 "Zend/zend_language_scanner.l" { if (CG(short_tags)) { BEGIN(ST_IN_SCRIPTING); @@ -1230,18 +1228,18 @@ yy7: goto inline_char_handler; } } -#line 1234 "Zend/zend_language_scanner.c" +#line 1232 "Zend/zend_language_scanner.c" yy8: YYDEBUG(8, *YYCURSOR); ++YYCURSOR; YYDEBUG(9, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1781 "Zend/zend_language_scanner.l" +#line 1779 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN(T_OPEN_TAG_WITH_ECHO); } -#line 1245 "Zend/zend_language_scanner.c" +#line 1243 "Zend/zend_language_scanner.c" yy10: YYDEBUG(10, *YYCURSOR); yych = *++YYCURSOR; @@ -1272,13 +1270,13 @@ yy14: yy15: YYDEBUG(15, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1787 "Zend/zend_language_scanner.l" +#line 1785 "Zend/zend_language_scanner.l" { HANDLE_NEWLINE(yytext[yyleng-1]); BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN(T_OPEN_TAG); } -#line 1282 "Zend/zend_language_scanner.c" +#line 1280 "Zend/zend_language_scanner.c" yy16: YYDEBUG(16, *YYCURSOR); ++YYCURSOR; @@ -1335,7 +1333,7 @@ yyc_ST_BACKQUOTE: yy20: YYDEBUG(20, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2216 "Zend/zend_language_scanner.l" +#line 2214 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -1376,7 +1374,7 @@ yy20: zend_scan_escape_string(zendlval, yytext, yyleng, '`'); RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE); } -#line 1380 "Zend/zend_language_scanner.c" +#line 1378 "Zend/zend_language_scanner.c" yy21: YYDEBUG(21, *YYCURSOR); yych = *++YYCURSOR; @@ -1400,12 +1398,12 @@ yy22: ++YYCURSOR; YYDEBUG(23, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2160 "Zend/zend_language_scanner.l" +#line 2158 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN('`'); } -#line 1409 "Zend/zend_language_scanner.c" +#line 1407 "Zend/zend_language_scanner.c" yy24: YYDEBUG(24, *YYCURSOR); yych = *++YYCURSOR; @@ -1426,36 +1424,36 @@ yy25: yy27: YYDEBUG(27, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1868 "Zend/zend_language_scanner.l" +#line 1866 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 1435 "Zend/zend_language_scanner.c" +#line 1433 "Zend/zend_language_scanner.c" yy28: YYDEBUG(28, *YYCURSOR); ++YYCURSOR; YYDEBUG(29, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1588 "Zend/zend_language_scanner.l" +#line 1586 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME); RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES); } -#line 1446 "Zend/zend_language_scanner.c" +#line 1444 "Zend/zend_language_scanner.c" yy30: YYDEBUG(30, *YYCURSOR); ++YYCURSOR; YYDEBUG(31, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2147 "Zend/zend_language_scanner.l" +#line 2145 "Zend/zend_language_scanner.l" { Z_LVAL_P(zendlval) = (zend_long) '{'; yy_push_state(ST_IN_SCRIPTING); yyless(1); RETURN_TOKEN(T_CURLY_OPEN); } -#line 1459 "Zend/zend_language_scanner.c" +#line 1457 "Zend/zend_language_scanner.c" yy32: YYDEBUG(32, *YYCURSOR); yych = *++YYCURSOR; @@ -1469,14 +1467,14 @@ yy34: ++YYCURSOR; YYDEBUG(35, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1861 "Zend/zend_language_scanner.l" +#line 1859 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_push_state(ST_VAR_OFFSET); zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 1480 "Zend/zend_language_scanner.c" +#line 1478 "Zend/zend_language_scanner.c" yy36: YYDEBUG(36, *YYCURSOR); yych = *++YYCURSOR; @@ -1494,14 +1492,14 @@ yy37: ++YYCURSOR; YYDEBUG(38, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1852 "Zend/zend_language_scanner.l" +#line 1850 "Zend/zend_language_scanner.l" { yyless(yyleng - 3); yy_push_state(ST_LOOKING_FOR_PROPERTY); zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 1505 "Zend/zend_language_scanner.c" +#line 1503 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_DOUBLE_QUOTES: @@ -1554,7 +1552,7 @@ yyc_ST_DOUBLE_QUOTES: yy42: YYDEBUG(42, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2166 "Zend/zend_language_scanner.l" +#line 2164 "Zend/zend_language_scanner.l" { if (GET_DOUBLE_QUOTES_SCANNED_LENGTH()) { YYCURSOR += GET_DOUBLE_QUOTES_SCANNED_LENGTH() - 1; @@ -1603,18 +1601,18 @@ double_quotes_scan_done: zend_scan_escape_string(zendlval, yytext, yyleng, '"'); RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE); } -#line 1607 "Zend/zend_language_scanner.c" +#line 1605 "Zend/zend_language_scanner.c" yy43: YYDEBUG(43, *YYCURSOR); ++YYCURSOR; YYDEBUG(44, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2155 "Zend/zend_language_scanner.l" +#line 2153 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN('"'); } -#line 1618 "Zend/zend_language_scanner.c" +#line 1616 "Zend/zend_language_scanner.c" yy45: YYDEBUG(45, *YYCURSOR); yych = *++YYCURSOR; @@ -1653,36 +1651,36 @@ yy47: yy49: YYDEBUG(49, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1868 "Zend/zend_language_scanner.l" +#line 1866 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 1662 "Zend/zend_language_scanner.c" +#line 1660 "Zend/zend_language_scanner.c" yy50: YYDEBUG(50, *YYCURSOR); ++YYCURSOR; YYDEBUG(51, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1588 "Zend/zend_language_scanner.l" +#line 1586 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME); RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES); } -#line 1673 "Zend/zend_language_scanner.c" +#line 1671 "Zend/zend_language_scanner.c" yy52: YYDEBUG(52, *YYCURSOR); ++YYCURSOR; YYDEBUG(53, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2147 "Zend/zend_language_scanner.l" +#line 2145 "Zend/zend_language_scanner.l" { Z_LVAL_P(zendlval) = (zend_long) '{'; yy_push_state(ST_IN_SCRIPTING); yyless(1); RETURN_TOKEN(T_CURLY_OPEN); } -#line 1686 "Zend/zend_language_scanner.c" +#line 1684 "Zend/zend_language_scanner.c" yy54: YYDEBUG(54, *YYCURSOR); yych = *++YYCURSOR; @@ -1696,14 +1694,14 @@ yy56: ++YYCURSOR; YYDEBUG(57, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1861 "Zend/zend_language_scanner.l" +#line 1859 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_push_state(ST_VAR_OFFSET); zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 1707 "Zend/zend_language_scanner.c" +#line 1705 "Zend/zend_language_scanner.c" yy58: YYDEBUG(58, *YYCURSOR); yych = *++YYCURSOR; @@ -1721,14 +1719,14 @@ yy59: ++YYCURSOR; YYDEBUG(60, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1852 "Zend/zend_language_scanner.l" +#line 1850 "Zend/zend_language_scanner.l" { yyless(yyleng - 3); yy_push_state(ST_LOOKING_FOR_PROPERTY); zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 1732 "Zend/zend_language_scanner.c" +#line 1730 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_END_HEREDOC: @@ -1739,7 +1737,7 @@ yyc_ST_END_HEREDOC: ++YYCURSOR; YYDEBUG(64, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2133 "Zend/zend_language_scanner.l" +#line 2131 "Zend/zend_language_scanner.l" { zend_heredoc_label *heredoc_label = zend_ptr_stack_pop(&SCNG(heredoc_label_stack)); @@ -1752,7 +1750,7 @@ yyc_ST_END_HEREDOC: BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN(T_END_HEREDOC); } -#line 1756 "Zend/zend_language_scanner.c" +#line 1754 "Zend/zend_language_scanner.c" /* *********************************** */ yyc_ST_HEREDOC: { @@ -1800,7 +1798,7 @@ yyc_ST_HEREDOC: yy68: YYDEBUG(68, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2258 "Zend/zend_language_scanner.l" +#line 2256 "Zend/zend_language_scanner.l" { int newline = 0; @@ -1873,7 +1871,7 @@ heredoc_scan_done: zend_scan_escape_string(zendlval, yytext, yyleng - newline, 0); RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE); } -#line 1877 "Zend/zend_language_scanner.c" +#line 1875 "Zend/zend_language_scanner.c" yy69: YYDEBUG(69, *YYCURSOR); yych = *++YYCURSOR; @@ -1912,36 +1910,36 @@ yy71: yy73: YYDEBUG(73, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1868 "Zend/zend_language_scanner.l" +#line 1866 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 1921 "Zend/zend_language_scanner.c" +#line 1919 "Zend/zend_language_scanner.c" yy74: YYDEBUG(74, *YYCURSOR); ++YYCURSOR; YYDEBUG(75, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1588 "Zend/zend_language_scanner.l" +#line 1586 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME); RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES); } -#line 1932 "Zend/zend_language_scanner.c" +#line 1930 "Zend/zend_language_scanner.c" yy76: YYDEBUG(76, *YYCURSOR); ++YYCURSOR; YYDEBUG(77, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2147 "Zend/zend_language_scanner.l" +#line 2145 "Zend/zend_language_scanner.l" { Z_LVAL_P(zendlval) = (zend_long) '{'; yy_push_state(ST_IN_SCRIPTING); yyless(1); RETURN_TOKEN(T_CURLY_OPEN); } -#line 1945 "Zend/zend_language_scanner.c" +#line 1943 "Zend/zend_language_scanner.c" yy78: YYDEBUG(78, *YYCURSOR); yych = *++YYCURSOR; @@ -1955,14 +1953,14 @@ yy80: ++YYCURSOR; YYDEBUG(81, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1861 "Zend/zend_language_scanner.l" +#line 1859 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_push_state(ST_VAR_OFFSET); zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 1966 "Zend/zend_language_scanner.c" +#line 1964 "Zend/zend_language_scanner.c" yy82: YYDEBUG(82, *YYCURSOR); yych = *++YYCURSOR; @@ -1980,14 +1978,14 @@ yy83: ++YYCURSOR; YYDEBUG(84, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1852 "Zend/zend_language_scanner.l" +#line 1850 "Zend/zend_language_scanner.l" { yyless(yyleng - 3); yy_push_state(ST_LOOKING_FOR_PROPERTY); zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 1991 "Zend/zend_language_scanner.c" +#line 1989 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_IN_SCRIPTING: @@ -2156,7 +2154,7 @@ yy87: ++YYCURSOR; YYDEBUG(88, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2389 "Zend/zend_language_scanner.l" +#line 2387 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -2165,7 +2163,7 @@ yy87: zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE); goto restart; } -#line 2169 "Zend/zend_language_scanner.c" +#line 2167 "Zend/zend_language_scanner.c" yy89: YYDEBUG(89, *YYCURSOR); ++YYCURSOR; @@ -2177,12 +2175,12 @@ yy89: } YYDEBUG(91, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1292 "Zend/zend_language_scanner.l" +#line 1290 "Zend/zend_language_scanner.l" { HANDLE_NEWLINES(yytext, yyleng); RETURN_TOKEN(T_WHITESPACE); } -#line 2186 "Zend/zend_language_scanner.c" +#line 2184 "Zend/zend_language_scanner.c" yy92: YYDEBUG(92, *YYCURSOR); ++YYCURSOR; @@ -2190,17 +2188,17 @@ yy92: yy93: YYDEBUG(93, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1577 "Zend/zend_language_scanner.l" +#line 1575 "Zend/zend_language_scanner.l" { RETURN_TOKEN(yytext[0]); } -#line 2198 "Zend/zend_language_scanner.c" +#line 2196 "Zend/zend_language_scanner.c" yy94: YYDEBUG(94, *YYCURSOR); ++YYCURSOR; YYDEBUG(95, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2037 "Zend/zend_language_scanner.l" +#line 2035 "Zend/zend_language_scanner.l" { int bprefix = (yytext[0] != '"') ? 1 : 0; @@ -2241,13 +2239,13 @@ yy94: BEGIN(ST_DOUBLE_QUOTES); RETURN_TOKEN('"'); } -#line 2245 "Zend/zend_language_scanner.c" +#line 2243 "Zend/zend_language_scanner.c" yy96: YYDEBUG(96, *YYCURSOR); ++YYCURSOR; YYDEBUG(97, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1897 "Zend/zend_language_scanner.l" +#line 1895 "Zend/zend_language_scanner.l" { while (YYCURSOR < YYLIMIT) { switch (*YYCURSOR++) { @@ -2276,7 +2274,7 @@ yy96: RETURN_TOKEN(T_COMMENT); } -#line 2280 "Zend/zend_language_scanner.c" +#line 2278 "Zend/zend_language_scanner.c" yy98: YYDEBUG(98, *YYCURSOR); yych = *++YYCURSOR; @@ -2307,7 +2305,7 @@ yy101: ++YYCURSOR; YYDEBUG(102, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1968 "Zend/zend_language_scanner.l" +#line 1966 "Zend/zend_language_scanner.l" { register char *s, *t; char *end; @@ -2375,7 +2373,7 @@ yy101: } RETURN_TOKEN(T_CONSTANT_ENCAPSED_STRING); } -#line 2379 "Zend/zend_language_scanner.c" +#line 2377 "Zend/zend_language_scanner.c" yy103: YYDEBUG(103, *YYCURSOR); yyaccept = 0; @@ -2505,7 +2503,7 @@ yy110: yy111: YYDEBUG(111, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1647 "Zend/zend_language_scanner.l" +#line 1645 "Zend/zend_language_scanner.l" { char *end; if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */ @@ -2548,7 +2546,7 @@ yy111: ZEND_ASSERT(!errno); RETURN_TOKEN(T_LNUMBER); } -#line 2552 "Zend/zend_language_scanner.c" +#line 2550 "Zend/zend_language_scanner.c" yy112: YYDEBUG(112, *YYCURSOR); yyaccept = 1; @@ -2629,12 +2627,12 @@ yy119: yy120: YYDEBUG(120, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1891 "Zend/zend_language_scanner.l" +#line 1889 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, yytext, yyleng); RETURN_TOKEN(T_STRING); } -#line 2638 "Zend/zend_language_scanner.c" +#line 2636 "Zend/zend_language_scanner.c" yy121: YYDEBUG(121, *YYCURSOR); yyaccept = 2; @@ -2919,11 +2917,11 @@ yy142: ++YYCURSOR; YYDEBUG(143, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1317 "Zend/zend_language_scanner.l" +#line 1315 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NS_SEPARATOR); } -#line 2927 "Zend/zend_language_scanner.c" +#line 2925 "Zend/zend_language_scanner.c" yy144: YYDEBUG(144, *YYCURSOR); yych = *++YYCURSOR; @@ -2939,23 +2937,23 @@ yy146: ++YYCURSOR; YYDEBUG(147, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2127 "Zend/zend_language_scanner.l" +#line 2125 "Zend/zend_language_scanner.l" { BEGIN(ST_BACKQUOTE); RETURN_TOKEN('`'); } -#line 2948 "Zend/zend_language_scanner.c" +#line 2946 "Zend/zend_language_scanner.c" yy148: YYDEBUG(148, *YYCURSOR); ++YYCURSOR; YYDEBUG(149, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1582 "Zend/zend_language_scanner.l" +#line 1580 "Zend/zend_language_scanner.l" { yy_push_state(ST_IN_SCRIPTING); RETURN_TOKEN('{'); } -#line 2959 "Zend/zend_language_scanner.c" +#line 2957 "Zend/zend_language_scanner.c" yy150: YYDEBUG(150, *YYCURSOR); yych = *++YYCURSOR; @@ -2967,7 +2965,7 @@ yy151: ++YYCURSOR; YYDEBUG(152, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1594 "Zend/zend_language_scanner.l" +#line 1592 "Zend/zend_language_scanner.l" { RESET_DOC_COMMENT(); if (!zend_stack_is_empty(&SCNG(state_stack))) { @@ -2975,7 +2973,7 @@ yy151: } RETURN_TOKEN('}'); } -#line 2979 "Zend/zend_language_scanner.c" +#line 2977 "Zend/zend_language_scanner.c" yy153: YYDEBUG(153, *YYCURSOR); ++YYCURSOR; @@ -2983,11 +2981,11 @@ yy153: yy154: YYDEBUG(154, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1481 "Zend/zend_language_scanner.l" +#line 1479 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_NOT_EQUAL); } -#line 2991 "Zend/zend_language_scanner.c" +#line 2989 "Zend/zend_language_scanner.c" yy155: YYDEBUG(155, *YYCURSOR); ++YYCURSOR; @@ -3012,42 +3010,42 @@ yy155: yy157: YYDEBUG(157, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1868 "Zend/zend_language_scanner.l" +#line 1866 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 3021 "Zend/zend_language_scanner.c" +#line 3019 "Zend/zend_language_scanner.c" yy158: YYDEBUG(158, *YYCURSOR); ++YYCURSOR; YYDEBUG(159, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1525 "Zend/zend_language_scanner.l" +#line 1523 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_MOD_EQUAL); } -#line 3031 "Zend/zend_language_scanner.c" +#line 3029 "Zend/zend_language_scanner.c" yy160: YYDEBUG(160, *YYCURSOR); ++YYCURSOR; YYDEBUG(161, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1553 "Zend/zend_language_scanner.l" +#line 1551 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BOOLEAN_AND); } -#line 3041 "Zend/zend_language_scanner.c" +#line 3039 "Zend/zend_language_scanner.c" yy162: YYDEBUG(162, *YYCURSOR); ++YYCURSOR; YYDEBUG(163, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1537 "Zend/zend_language_scanner.l" +#line 1535 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_AND_EQUAL); } -#line 3051 "Zend/zend_language_scanner.c" +#line 3049 "Zend/zend_language_scanner.c" yy164: YYDEBUG(164, *YYCURSOR); ++YYCURSOR; @@ -3177,72 +3175,72 @@ yy176: if ((yych = *YYCURSOR) == '=') goto yy289; YYDEBUG(177, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1509 "Zend/zend_language_scanner.l" +#line 1507 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_POW); } -#line 3185 "Zend/zend_language_scanner.c" +#line 3183 "Zend/zend_language_scanner.c" yy178: YYDEBUG(178, *YYCURSOR); ++YYCURSOR; YYDEBUG(179, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1505 "Zend/zend_language_scanner.l" +#line 1503 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_MUL_EQUAL); } -#line 3195 "Zend/zend_language_scanner.c" +#line 3193 "Zend/zend_language_scanner.c" yy180: YYDEBUG(180, *YYCURSOR); ++YYCURSOR; YYDEBUG(181, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1461 "Zend/zend_language_scanner.l" +#line 1459 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INC); } -#line 3205 "Zend/zend_language_scanner.c" +#line 3203 "Zend/zend_language_scanner.c" yy182: YYDEBUG(182, *YYCURSOR); ++YYCURSOR; YYDEBUG(183, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1497 "Zend/zend_language_scanner.l" +#line 1495 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PLUS_EQUAL); } -#line 3215 "Zend/zend_language_scanner.c" +#line 3213 "Zend/zend_language_scanner.c" yy184: YYDEBUG(184, *YYCURSOR); ++YYCURSOR; YYDEBUG(185, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1465 "Zend/zend_language_scanner.l" +#line 1463 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DEC); } -#line 3225 "Zend/zend_language_scanner.c" +#line 3223 "Zend/zend_language_scanner.c" yy186: YYDEBUG(186, *YYCURSOR); ++YYCURSOR; YYDEBUG(187, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1501 "Zend/zend_language_scanner.l" +#line 1499 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_MINUS_EQUAL); } -#line 3235 "Zend/zend_language_scanner.c" +#line 3233 "Zend/zend_language_scanner.c" yy188: YYDEBUG(188, *YYCURSOR); ++YYCURSOR; YYDEBUG(189, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1287 "Zend/zend_language_scanner.l" +#line 1285 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_PROPERTY); RETURN_TOKEN(T_OBJECT_OPERATOR); } -#line 3246 "Zend/zend_language_scanner.c" +#line 3244 "Zend/zend_language_scanner.c" yy190: YYDEBUG(190, *YYCURSOR); yych = *++YYCURSOR; @@ -3265,7 +3263,7 @@ yy191: yy193: YYDEBUG(193, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1739 "Zend/zend_language_scanner.l" +#line 1737 "Zend/zend_language_scanner.l" { const char *end; @@ -3274,17 +3272,17 @@ yy193: ZEND_ASSERT(end == yytext + yyleng); RETURN_TOKEN(T_DNUMBER); } -#line 3278 "Zend/zend_language_scanner.c" +#line 3276 "Zend/zend_language_scanner.c" yy194: YYDEBUG(194, *YYCURSOR); ++YYCURSOR; YYDEBUG(195, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1521 "Zend/zend_language_scanner.l" +#line 1519 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CONCAT_EQUAL); } -#line 3288 "Zend/zend_language_scanner.c" +#line 3286 "Zend/zend_language_scanner.c" yy196: YYDEBUG(196, *YYCURSOR); yyaccept = 4; @@ -3293,7 +3291,7 @@ yy196: yy197: YYDEBUG(197, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1926 "Zend/zend_language_scanner.l" +#line 1924 "Zend/zend_language_scanner.l" { int doc_com; @@ -3326,17 +3324,17 @@ yy197: RETURN_TOKEN(T_COMMENT); } -#line 3330 "Zend/zend_language_scanner.c" +#line 3328 "Zend/zend_language_scanner.c" yy198: YYDEBUG(198, *YYCURSOR); ++YYCURSOR; YYDEBUG(199, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1517 "Zend/zend_language_scanner.l" +#line 1515 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DIV_EQUAL); } -#line 3340 "Zend/zend_language_scanner.c" +#line 3338 "Zend/zend_language_scanner.c" yy200: YYDEBUG(200, *YYCURSOR); yych = *++YYCURSOR; @@ -3368,11 +3366,11 @@ yy203: ++YYCURSOR; YYDEBUG(204, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1313 "Zend/zend_language_scanner.l" +#line 1311 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PAAMAYIM_NEKUDOTAYIM); } -#line 3376 "Zend/zend_language_scanner.c" +#line 3374 "Zend/zend_language_scanner.c" yy205: YYDEBUG(205, *YYCURSOR); yyaccept = 5; @@ -3383,22 +3381,22 @@ yy205: yy206: YYDEBUG(206, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1569 "Zend/zend_language_scanner.l" +#line 1567 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SL); } -#line 3391 "Zend/zend_language_scanner.c" +#line 3389 "Zend/zend_language_scanner.c" yy207: YYDEBUG(207, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) == '>') goto yy307; YYDEBUG(208, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1489 "Zend/zend_language_scanner.l" +#line 1487 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_SMALLER_OR_EQUAL); } -#line 3402 "Zend/zend_language_scanner.c" +#line 3400 "Zend/zend_language_scanner.c" yy209: YYDEBUG(209, *YYCURSOR); yych = *++YYCURSOR; @@ -3409,42 +3407,42 @@ yy210: if ((yych = *YYCURSOR) == '=') goto yy309; YYDEBUG(211, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1477 "Zend/zend_language_scanner.l" +#line 1475 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_EQUAL); } -#line 3417 "Zend/zend_language_scanner.c" +#line 3415 "Zend/zend_language_scanner.c" yy212: YYDEBUG(212, *YYCURSOR); ++YYCURSOR; YYDEBUG(213, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1445 "Zend/zend_language_scanner.l" +#line 1443 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DOUBLE_ARROW); } -#line 3427 "Zend/zend_language_scanner.c" +#line 3425 "Zend/zend_language_scanner.c" yy214: YYDEBUG(214, *YYCURSOR); ++YYCURSOR; YYDEBUG(215, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1493 "Zend/zend_language_scanner.l" +#line 1491 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_GREATER_OR_EQUAL); } -#line 3437 "Zend/zend_language_scanner.c" +#line 3435 "Zend/zend_language_scanner.c" yy216: YYDEBUG(216, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) == '=') goto yy311; YYDEBUG(217, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1573 "Zend/zend_language_scanner.l" +#line 1571 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SR); } -#line 3448 "Zend/zend_language_scanner.c" +#line 3446 "Zend/zend_language_scanner.c" yy218: YYDEBUG(218, *YYCURSOR); ++YYCURSOR; @@ -3453,7 +3451,7 @@ yy218: yy219: YYDEBUG(219, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1959 "Zend/zend_language_scanner.l" +#line 1957 "Zend/zend_language_scanner.l" { BEGIN(INITIAL); if (yytext[yyleng-1] != '>') { @@ -3461,17 +3459,17 @@ yy219: } RETURN_TOKEN(T_CLOSE_TAG); /* implicit ';' at php-end tag */ } -#line 3465 "Zend/zend_language_scanner.c" +#line 3463 "Zend/zend_language_scanner.c" yy220: YYDEBUG(220, *YYCURSOR); ++YYCURSOR; YYDEBUG(221, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1325 "Zend/zend_language_scanner.l" +#line 1323 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_COALESCE); } -#line 3475 "Zend/zend_language_scanner.c" +#line 3473 "Zend/zend_language_scanner.c" yy222: YYDEBUG(222, *YYCURSOR); yych = *++YYCURSOR; @@ -3498,11 +3496,11 @@ yy225: } YYDEBUG(226, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1227 "Zend/zend_language_scanner.l" +#line 1225 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_AS); } -#line 3506 "Zend/zend_language_scanner.c" +#line 3504 "Zend/zend_language_scanner.c" yy227: YYDEBUG(227, *YYCURSOR); yych = *++YYCURSOR; @@ -3588,11 +3586,11 @@ yy234: } YYDEBUG(235, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1195 "Zend/zend_language_scanner.l" +#line 1193 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DO); } -#line 3596 "Zend/zend_language_scanner.c" +#line 3594 "Zend/zend_language_scanner.c" yy236: YYDEBUG(236, *YYCURSOR); yych = *++YYCURSOR; @@ -3677,11 +3675,11 @@ yy247: } YYDEBUG(248, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1171 "Zend/zend_language_scanner.l" +#line 1169 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IF); } -#line 3685 "Zend/zend_language_scanner.c" +#line 3683 "Zend/zend_language_scanner.c" yy249: YYDEBUG(249, *YYCURSOR); yych = *++YYCURSOR; @@ -3742,11 +3740,11 @@ yy255: } YYDEBUG(256, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1557 "Zend/zend_language_scanner.l" +#line 1555 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LOGICAL_OR); } -#line 3750 "Zend/zend_language_scanner.c" +#line 3748 "Zend/zend_language_scanner.c" yy257: YYDEBUG(257, *YYCURSOR); yych = *++YYCURSOR; @@ -3860,11 +3858,11 @@ yy270: ++YYCURSOR; YYDEBUG(271, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1545 "Zend/zend_language_scanner.l" +#line 1543 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_XOR_EQUAL); } -#line 3868 "Zend/zend_language_scanner.c" +#line 3866 "Zend/zend_language_scanner.c" yy272: YYDEBUG(272, *YYCURSOR); yych = *++YYCURSOR; @@ -3892,31 +3890,31 @@ yy273: ++YYCURSOR; YYDEBUG(274, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1541 "Zend/zend_language_scanner.l" +#line 1539 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_OR_EQUAL); } -#line 3900 "Zend/zend_language_scanner.c" +#line 3898 "Zend/zend_language_scanner.c" yy275: YYDEBUG(275, *YYCURSOR); ++YYCURSOR; YYDEBUG(276, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1549 "Zend/zend_language_scanner.l" +#line 1547 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BOOLEAN_OR); } -#line 3910 "Zend/zend_language_scanner.c" +#line 3908 "Zend/zend_language_scanner.c" yy277: YYDEBUG(277, *YYCURSOR); ++YYCURSOR; YYDEBUG(278, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1473 "Zend/zend_language_scanner.l" +#line 1471 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_NOT_IDENTICAL); } -#line 3920 "Zend/zend_language_scanner.c" +#line 3918 "Zend/zend_language_scanner.c" yy279: YYDEBUG(279, *YYCURSOR); yych = *++YYCURSOR; @@ -3982,21 +3980,21 @@ yy289: ++YYCURSOR; YYDEBUG(290, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1513 "Zend/zend_language_scanner.l" +#line 1511 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_POW_EQUAL); } -#line 3990 "Zend/zend_language_scanner.c" +#line 3988 "Zend/zend_language_scanner.c" yy291: YYDEBUG(291, *YYCURSOR); ++YYCURSOR; YYDEBUG(292, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1321 "Zend/zend_language_scanner.l" +#line 1319 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ELLIPSIS); } -#line 4000 "Zend/zend_language_scanner.c" +#line 3998 "Zend/zend_language_scanner.c" yy293: YYDEBUG(293, *YYCURSOR); yych = *++YYCURSOR; @@ -4020,7 +4018,7 @@ yy294: } YYDEBUG(296, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1619 "Zend/zend_language_scanner.l" +#line 1617 "Zend/zend_language_scanner.l" { char *bin = yytext + 2; /* Skip "0b" */ int len = yyleng - 2; @@ -4048,7 +4046,7 @@ yy294: RETURN_TOKEN(T_DNUMBER); } } -#line 4052 "Zend/zend_language_scanner.c" +#line 4050 "Zend/zend_language_scanner.c" yy297: YYDEBUG(297, *YYCURSOR); yych = *++YYCURSOR; @@ -4074,7 +4072,7 @@ yy300: } YYDEBUG(302, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1690 "Zend/zend_language_scanner.l" +#line 1688 "Zend/zend_language_scanner.l" { char *hex = yytext + 2; /* Skip "0x" */ int len = yyleng - 2; @@ -4102,7 +4100,7 @@ yy300: RETURN_TOKEN(T_DNUMBER); } } -#line 4106 "Zend/zend_language_scanner.c" +#line 4104 "Zend/zend_language_scanner.c" yy303: YYDEBUG(303, *YYCURSOR); ++YYCURSOR; @@ -4137,41 +4135,41 @@ yy305: ++YYCURSOR; YYDEBUG(306, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1529 "Zend/zend_language_scanner.l" +#line 1527 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SL_EQUAL); } -#line 4145 "Zend/zend_language_scanner.c" +#line 4143 "Zend/zend_language_scanner.c" yy307: YYDEBUG(307, *YYCURSOR); ++YYCURSOR; YYDEBUG(308, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1485 "Zend/zend_language_scanner.l" +#line 1483 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SPACESHIP); } -#line 4155 "Zend/zend_language_scanner.c" +#line 4153 "Zend/zend_language_scanner.c" yy309: YYDEBUG(309, *YYCURSOR); ++YYCURSOR; YYDEBUG(310, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1469 "Zend/zend_language_scanner.l" +#line 1467 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_IDENTICAL); } -#line 4165 "Zend/zend_language_scanner.c" +#line 4163 "Zend/zend_language_scanner.c" yy311: YYDEBUG(311, *YYCURSOR); ++YYCURSOR; YYDEBUG(312, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1533 "Zend/zend_language_scanner.l" +#line 1531 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SR_EQUAL); } -#line 4175 "Zend/zend_language_scanner.c" +#line 4173 "Zend/zend_language_scanner.c" yy313: YYDEBUG(313, *YYCURSOR); yych = *++YYCURSOR; @@ -4195,11 +4193,11 @@ yy316: } YYDEBUG(317, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1561 "Zend/zend_language_scanner.l" +#line 1559 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LOGICAL_AND); } -#line 4203 "Zend/zend_language_scanner.c" +#line 4201 "Zend/zend_language_scanner.c" yy318: YYDEBUG(318, *YYCURSOR); yych = *++YYCURSOR; @@ -4280,11 +4278,11 @@ yy329: } YYDEBUG(330, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1129 "Zend/zend_language_scanner.l" +#line 1127 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EXIT); } -#line 4288 "Zend/zend_language_scanner.c" +#line 4286 "Zend/zend_language_scanner.c" yy331: YYDEBUG(331, *YYCURSOR); yych = *++YYCURSOR; @@ -4366,11 +4364,11 @@ yy339: yy340: YYDEBUG(340, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1199 "Zend/zend_language_scanner.l" +#line 1197 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FOR); } -#line 4374 "Zend/zend_language_scanner.c" +#line 4372 "Zend/zend_language_scanner.c" yy341: YYDEBUG(341, *YYCURSOR); yych = *++YYCURSOR; @@ -4439,11 +4437,11 @@ yy351: } YYDEBUG(352, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1329 "Zend/zend_language_scanner.l" +#line 1327 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NEW); } -#line 4447 "Zend/zend_language_scanner.c" +#line 4445 "Zend/zend_language_scanner.c" yy353: YYDEBUG(353, *YYCURSOR); yych = *++YYCURSOR; @@ -4516,11 +4514,11 @@ yy362: } YYDEBUG(363, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1155 "Zend/zend_language_scanner.l" +#line 1153 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_TRY); } -#line 4524 "Zend/zend_language_scanner.c" +#line 4522 "Zend/zend_language_scanner.c" yy364: YYDEBUG(364, *YYCURSOR); yych = *++YYCURSOR; @@ -4535,11 +4533,11 @@ yy365: } YYDEBUG(366, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1393 "Zend/zend_language_scanner.l" +#line 1391 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_USE); } -#line 4543 "Zend/zend_language_scanner.c" +#line 4541 "Zend/zend_language_scanner.c" yy367: YYDEBUG(367, *YYCURSOR); ++YYCURSOR; @@ -4548,11 +4546,11 @@ yy367: } YYDEBUG(368, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1337 "Zend/zend_language_scanner.l" +#line 1335 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_VAR); } -#line 4556 "Zend/zend_language_scanner.c" +#line 4554 "Zend/zend_language_scanner.c" yy369: YYDEBUG(369, *YYCURSOR); yych = *++YYCURSOR; @@ -4567,11 +4565,11 @@ yy370: } YYDEBUG(371, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1565 "Zend/zend_language_scanner.l" +#line 1563 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LOGICAL_XOR); } -#line 4575 "Zend/zend_language_scanner.c" +#line 4573 "Zend/zend_language_scanner.c" yy372: YYDEBUG(372, *YYCURSOR); yych = *++YYCURSOR; @@ -4785,11 +4783,11 @@ yy401: } YYDEBUG(402, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1239 "Zend/zend_language_scanner.l" +#line 1237 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CASE); } -#line 4793 "Zend/zend_language_scanner.c" +#line 4791 "Zend/zend_language_scanner.c" yy403: YYDEBUG(403, *YYCURSOR); yych = *++YYCURSOR; @@ -4840,11 +4838,11 @@ yy410: } YYDEBUG(411, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1259 "Zend/zend_language_scanner.l" +#line 1257 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ECHO); } -#line 4848 "Zend/zend_language_scanner.c" +#line 4846 "Zend/zend_language_scanner.c" yy412: YYDEBUG(412, *YYCURSOR); ++YYCURSOR; @@ -4868,11 +4866,11 @@ yy412: yy413: YYDEBUG(413, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1183 "Zend/zend_language_scanner.l" +#line 1181 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ELSE); } -#line 4876 "Zend/zend_language_scanner.c" +#line 4874 "Zend/zend_language_scanner.c" yy414: YYDEBUG(414, *YYCURSOR); yych = *++YYCURSOR; @@ -4917,11 +4915,11 @@ yy420: } YYDEBUG(421, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1369 "Zend/zend_language_scanner.l" +#line 1367 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EVAL); } -#line 4925 "Zend/zend_language_scanner.c" +#line 4923 "Zend/zend_language_scanner.c" yy422: YYDEBUG(422, *YYCURSOR); ++YYCURSOR; @@ -4930,11 +4928,11 @@ yy422: } YYDEBUG(423, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1125 "Zend/zend_language_scanner.l" +#line 1123 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EXIT); } -#line 4938 "Zend/zend_language_scanner.c" +#line 4936 "Zend/zend_language_scanner.c" yy424: YYDEBUG(424, *YYCURSOR); yych = *++YYCURSOR; @@ -4973,11 +4971,11 @@ yy429: } YYDEBUG(430, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1255 "Zend/zend_language_scanner.l" +#line 1253 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_GOTO); } -#line 4981 "Zend/zend_language_scanner.c" +#line 4979 "Zend/zend_language_scanner.c" yy431: YYDEBUG(431, *YYCURSOR); yych = *++YYCURSOR; @@ -5026,11 +5024,11 @@ yy436: } YYDEBUG(437, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1449 "Zend/zend_language_scanner.l" +#line 1447 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LIST); } -#line 5034 "Zend/zend_language_scanner.c" +#line 5032 "Zend/zend_language_scanner.c" yy438: YYDEBUG(438, *YYCURSOR); yych = *++YYCURSOR; @@ -5217,11 +5215,11 @@ yy467: ++YYCURSOR; YYDEBUG(469, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1341 "Zend/zend_language_scanner.l" +#line 1339 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INT_CAST); } -#line 5225 "Zend/zend_language_scanner.c" +#line 5223 "Zend/zend_language_scanner.c" yy470: YYDEBUG(470, *YYCURSOR); yych = *++YYCURSOR; @@ -5318,7 +5316,7 @@ yy480: yy481: YYDEBUG(481, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2079 "Zend/zend_language_scanner.l" +#line 2077 "Zend/zend_language_scanner.l" { char *s; int bprefix = (yytext[0] != '<') ? 1 : 0; @@ -5365,7 +5363,7 @@ yy481: RETURN_TOKEN(T_START_HEREDOC); } -#line 5369 "Zend/zend_language_scanner.c" +#line 5367 "Zend/zend_language_scanner.c" yy482: YYDEBUG(482, *YYCURSOR); yych = *++YYCURSOR; @@ -5385,11 +5383,11 @@ yy484: } YYDEBUG(485, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1453 "Zend/zend_language_scanner.l" +#line 1451 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ARRAY); } -#line 5393 "Zend/zend_language_scanner.c" +#line 5391 "Zend/zend_language_scanner.c" yy486: YYDEBUG(486, *YYCURSOR); ++YYCURSOR; @@ -5398,11 +5396,11 @@ yy486: } YYDEBUG(487, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1247 "Zend/zend_language_scanner.l" +#line 1245 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BREAK); } -#line 5406 "Zend/zend_language_scanner.c" +#line 5404 "Zend/zend_language_scanner.c" yy488: YYDEBUG(488, *YYCURSOR); yych = *++YYCURSOR; @@ -5417,11 +5415,11 @@ yy489: } YYDEBUG(490, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1159 "Zend/zend_language_scanner.l" +#line 1157 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CATCH); } -#line 5425 "Zend/zend_language_scanner.c" +#line 5423 "Zend/zend_language_scanner.c" yy491: YYDEBUG(491, *YYCURSOR); ++YYCURSOR; @@ -5430,11 +5428,11 @@ yy491: } YYDEBUG(492, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1267 "Zend/zend_language_scanner.l" +#line 1265 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CLASS); } -#line 5438 "Zend/zend_language_scanner.c" +#line 5436 "Zend/zend_language_scanner.c" yy493: YYDEBUG(493, *YYCURSOR); ++YYCURSOR; @@ -5443,11 +5441,11 @@ yy493: } YYDEBUG(494, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1333 "Zend/zend_language_scanner.l" +#line 1331 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CLONE); } -#line 5451 "Zend/zend_language_scanner.c" +#line 5449 "Zend/zend_language_scanner.c" yy495: YYDEBUG(495, *YYCURSOR); ++YYCURSOR; @@ -5456,11 +5454,11 @@ yy495: } YYDEBUG(496, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1137 "Zend/zend_language_scanner.l" +#line 1135 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CONST); } -#line 5464 "Zend/zend_language_scanner.c" +#line 5462 "Zend/zend_language_scanner.c" yy497: YYDEBUG(497, *YYCURSOR); yych = *++YYCURSOR; @@ -5493,11 +5491,11 @@ yy501: } YYDEBUG(502, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1409 "Zend/zend_language_scanner.l" +#line 1407 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EMPTY); } -#line 5501 "Zend/zend_language_scanner.c" +#line 5499 "Zend/zend_language_scanner.c" yy503: YYDEBUG(503, *YYCURSOR); yych = *++YYCURSOR; @@ -5518,11 +5516,11 @@ yy505: } YYDEBUG(506, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1179 "Zend/zend_language_scanner.l" +#line 1177 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDIF); } -#line 5526 "Zend/zend_language_scanner.c" +#line 5524 "Zend/zend_language_scanner.c" yy507: YYDEBUG(507, *YYCURSOR); yych = *++YYCURSOR; @@ -5564,11 +5562,11 @@ yy510: yy511: YYDEBUG(511, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1425 "Zend/zend_language_scanner.l" +#line 1423 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FINAL); } -#line 5572 "Zend/zend_language_scanner.c" +#line 5570 "Zend/zend_language_scanner.c" yy512: YYDEBUG(512, *YYCURSOR); yych = *++YYCURSOR; @@ -5625,11 +5623,11 @@ yy520: } YYDEBUG(521, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1405 "Zend/zend_language_scanner.l" +#line 1403 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ISSET); } -#line 5633 "Zend/zend_language_scanner.c" +#line 5631 "Zend/zend_language_scanner.c" yy522: YYDEBUG(522, *YYCURSOR); yych = *++YYCURSOR; @@ -5644,11 +5642,11 @@ yy523: } YYDEBUG(524, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1263 "Zend/zend_language_scanner.l" +#line 1261 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PRINT); } -#line 5652 "Zend/zend_language_scanner.c" +#line 5650 "Zend/zend_language_scanner.c" yy525: YYDEBUG(525, *YYCURSOR); yych = *++YYCURSOR; @@ -5699,11 +5697,11 @@ yy532: } YYDEBUG(533, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1167 "Zend/zend_language_scanner.l" +#line 1165 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_THROW); } -#line 5707 "Zend/zend_language_scanner.c" +#line 5705 "Zend/zend_language_scanner.c" yy534: YYDEBUG(534, *YYCURSOR); ++YYCURSOR; @@ -5712,11 +5710,11 @@ yy534: } YYDEBUG(535, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1275 "Zend/zend_language_scanner.l" +#line 1273 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_TRAIT); } -#line 5720 "Zend/zend_language_scanner.c" +#line 5718 "Zend/zend_language_scanner.c" yy536: YYDEBUG(536, *YYCURSOR); ++YYCURSOR; @@ -5725,11 +5723,11 @@ yy536: } YYDEBUG(537, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1441 "Zend/zend_language_scanner.l" +#line 1439 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_UNSET); } -#line 5733 "Zend/zend_language_scanner.c" +#line 5731 "Zend/zend_language_scanner.c" yy538: YYDEBUG(538, *YYCURSOR); ++YYCURSOR; @@ -5738,11 +5736,11 @@ yy538: } YYDEBUG(539, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1187 "Zend/zend_language_scanner.l" +#line 1185 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_WHILE); } -#line 5746 "Zend/zend_language_scanner.c" +#line 5744 "Zend/zend_language_scanner.c" yy540: YYDEBUG(540, *YYCURSOR); yyaccept = 6; @@ -5760,11 +5758,11 @@ yy540: yy541: YYDEBUG(541, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1151 "Zend/zend_language_scanner.l" +#line 1149 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_YIELD); } -#line 5768 "Zend/zend_language_scanner.c" +#line 5766 "Zend/zend_language_scanner.c" yy542: YYDEBUG(542, *YYCURSOR); yych = *++YYCURSOR; @@ -5856,11 +5854,11 @@ yy555: ++YYCURSOR; YYDEBUG(557, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1361 "Zend/zend_language_scanner.l" +#line 1359 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BOOL_CAST); } -#line 5864 "Zend/zend_language_scanner.c" +#line 5862 "Zend/zend_language_scanner.c" yy558: YYDEBUG(558, *YYCURSOR); yych = *++YYCURSOR; @@ -5890,11 +5888,11 @@ yy562: ++YYCURSOR; YYDEBUG(563, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1345 "Zend/zend_language_scanner.l" +#line 1343 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DOUBLE_CAST); } -#line 5898 "Zend/zend_language_scanner.c" +#line 5896 "Zend/zend_language_scanner.c" yy564: YYDEBUG(564, *YYCURSOR); yych = *++YYCURSOR; @@ -5959,11 +5957,11 @@ yy573: } YYDEBUG(574, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1175 "Zend/zend_language_scanner.l" +#line 1173 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ELSEIF); } -#line 5967 "Zend/zend_language_scanner.c" +#line 5965 "Zend/zend_language_scanner.c" yy575: YYDEBUG(575, *YYCURSOR); yych = *++YYCURSOR; @@ -5993,11 +5991,11 @@ yy576: yy577: YYDEBUG(577, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1203 "Zend/zend_language_scanner.l" +#line 1201 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDFOR); } -#line 6001 "Zend/zend_language_scanner.c" +#line 5999 "Zend/zend_language_scanner.c" yy578: YYDEBUG(578, *YYCURSOR); yych = *++YYCURSOR; @@ -6042,11 +6040,11 @@ yy584: } YYDEBUG(585, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1401 "Zend/zend_language_scanner.l" +#line 1399 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_GLOBAL); } -#line 6050 "Zend/zend_language_scanner.c" +#line 6048 "Zend/zend_language_scanner.c" yy586: YYDEBUG(586, *YYCURSOR); yych = *++YYCURSOR; @@ -6103,11 +6101,11 @@ yy594: } YYDEBUG(595, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1437 "Zend/zend_language_scanner.l" +#line 1435 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PUBLIC); } -#line 6111 "Zend/zend_language_scanner.c" +#line 6109 "Zend/zend_language_scanner.c" yy596: YYDEBUG(596, *YYCURSOR); yych = *++YYCURSOR; @@ -6122,11 +6120,11 @@ yy597: } YYDEBUG(598, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1141 "Zend/zend_language_scanner.l" +#line 1139 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_RETURN); } -#line 6130 "Zend/zend_language_scanner.c" +#line 6128 "Zend/zend_language_scanner.c" yy599: YYDEBUG(599, *YYCURSOR); ++YYCURSOR; @@ -6135,11 +6133,11 @@ yy599: } YYDEBUG(600, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1417 "Zend/zend_language_scanner.l" +#line 1415 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_STATIC); } -#line 6143 "Zend/zend_language_scanner.c" +#line 6141 "Zend/zend_language_scanner.c" yy601: YYDEBUG(601, *YYCURSOR); ++YYCURSOR; @@ -6148,11 +6146,11 @@ yy601: } YYDEBUG(602, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1231 "Zend/zend_language_scanner.l" +#line 1229 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SWITCH); } -#line 6156 "Zend/zend_language_scanner.c" +#line 6154 "Zend/zend_language_scanner.c" yy603: YYDEBUG(603, *YYCURSOR); ++YYCURSOR; @@ -6232,11 +6230,11 @@ yy614: ++YYCURSOR; YYDEBUG(615, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1353 "Zend/zend_language_scanner.l" +#line 1351 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ARRAY_CAST); } -#line 6240 "Zend/zend_language_scanner.c" +#line 6238 "Zend/zend_language_scanner.c" yy616: YYDEBUG(616, *YYCURSOR); ++YYCURSOR; @@ -6282,11 +6280,11 @@ yy622: ++YYCURSOR; YYDEBUG(623, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1365 "Zend/zend_language_scanner.l" +#line 1363 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_UNSET_CAST); } -#line 6290 "Zend/zend_language_scanner.c" +#line 6288 "Zend/zend_language_scanner.c" yy624: YYDEBUG(624, *YYCURSOR); yych = *++YYCURSOR; @@ -6313,11 +6311,11 @@ yy627: } YYDEBUG(628, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1215 "Zend/zend_language_scanner.l" +#line 1213 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DECLARE); } -#line 6321 "Zend/zend_language_scanner.c" +#line 6319 "Zend/zend_language_scanner.c" yy629: YYDEBUG(629, *YYCURSOR); ++YYCURSOR; @@ -6326,11 +6324,11 @@ yy629: } YYDEBUG(630, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1243 "Zend/zend_language_scanner.l" +#line 1241 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DEFAULT); } -#line 6334 "Zend/zend_language_scanner.c" +#line 6332 "Zend/zend_language_scanner.c" yy631: YYDEBUG(631, *YYCURSOR); yych = *++YYCURSOR; @@ -6363,11 +6361,11 @@ yy635: } YYDEBUG(636, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1279 "Zend/zend_language_scanner.l" +#line 1277 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EXTENDS); } -#line 6371 "Zend/zend_language_scanner.c" +#line 6369 "Zend/zend_language_scanner.c" yy637: YYDEBUG(637, *YYCURSOR); ++YYCURSOR; @@ -6376,11 +6374,11 @@ yy637: } YYDEBUG(638, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1163 "Zend/zend_language_scanner.l" +#line 1161 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FINALLY); } -#line 6384 "Zend/zend_language_scanner.c" +#line 6382 "Zend/zend_language_scanner.c" yy639: YYDEBUG(639, *YYCURSOR); ++YYCURSOR; @@ -6389,11 +6387,11 @@ yy639: } YYDEBUG(640, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1207 "Zend/zend_language_scanner.l" +#line 1205 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FOREACH); } -#line 6397 "Zend/zend_language_scanner.c" +#line 6395 "Zend/zend_language_scanner.c" yy641: YYDEBUG(641, *YYCURSOR); yych = *++YYCURSOR; @@ -6427,11 +6425,11 @@ yy643: yy644: YYDEBUG(644, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1373 "Zend/zend_language_scanner.l" +#line 1371 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INCLUDE); } -#line 6435 "Zend/zend_language_scanner.c" +#line 6433 "Zend/zend_language_scanner.c" yy645: YYDEBUG(645, *YYCURSOR); yych = *++YYCURSOR; @@ -6464,11 +6462,11 @@ yy649: } YYDEBUG(650, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1429 "Zend/zend_language_scanner.l" +#line 1427 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PRIVATE); } -#line 6472 "Zend/zend_language_scanner.c" +#line 6470 "Zend/zend_language_scanner.c" yy651: YYDEBUG(651, *YYCURSOR); yych = *++YYCURSOR; @@ -6496,11 +6494,11 @@ yy652: yy653: YYDEBUG(653, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1381 "Zend/zend_language_scanner.l" +#line 1379 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_REQUIRE); } -#line 6504 "Zend/zend_language_scanner.c" +#line 6502 "Zend/zend_language_scanner.c" yy654: YYDEBUG(654, *YYCURSOR); yych = *++YYCURSOR; @@ -6520,11 +6518,11 @@ yy656: } YYDEBUG(657, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1772 "Zend/zend_language_scanner.l" +#line 1770 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DIR); } -#line 6528 "Zend/zend_language_scanner.c" +#line 6526 "Zend/zend_language_scanner.c" yy658: YYDEBUG(658, *YYCURSOR); yych = *++YYCURSOR; @@ -6569,21 +6567,21 @@ yy665: ++YYCURSOR; YYDEBUG(666, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1349 "Zend/zend_language_scanner.l" +#line 1347 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_STRING_CAST); } -#line 6577 "Zend/zend_language_scanner.c" +#line 6575 "Zend/zend_language_scanner.c" yy667: YYDEBUG(667, *YYCURSOR); ++YYCURSOR; YYDEBUG(668, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1357 "Zend/zend_language_scanner.l" +#line 1355 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_OBJECT_CAST); } -#line 6587 "Zend/zend_language_scanner.c" +#line 6585 "Zend/zend_language_scanner.c" yy669: YYDEBUG(669, *YYCURSOR); ++YYCURSOR; @@ -6592,11 +6590,11 @@ yy669: } YYDEBUG(670, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1421 "Zend/zend_language_scanner.l" +#line 1419 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ABSTRACT); } -#line 6600 "Zend/zend_language_scanner.c" +#line 6598 "Zend/zend_language_scanner.c" yy671: YYDEBUG(671, *YYCURSOR); ++YYCURSOR; @@ -6605,11 +6603,11 @@ yy671: } YYDEBUG(672, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1457 "Zend/zend_language_scanner.l" +#line 1455 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CALLABLE); } -#line 6613 "Zend/zend_language_scanner.c" +#line 6611 "Zend/zend_language_scanner.c" yy673: YYDEBUG(673, *YYCURSOR); ++YYCURSOR; @@ -6618,11 +6616,11 @@ yy673: } YYDEBUG(674, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1251 "Zend/zend_language_scanner.l" +#line 1249 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CONTINUE); } -#line 6626 "Zend/zend_language_scanner.c" +#line 6624 "Zend/zend_language_scanner.c" yy675: YYDEBUG(675, *YYCURSOR); yych = *++YYCURSOR; @@ -6649,11 +6647,11 @@ yy678: } YYDEBUG(679, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1191 "Zend/zend_language_scanner.l" +#line 1189 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDWHILE); } -#line 6657 "Zend/zend_language_scanner.c" +#line 6655 "Zend/zend_language_scanner.c" yy680: YYDEBUG(680, *YYCURSOR); ++YYCURSOR; @@ -6662,11 +6660,11 @@ yy680: } YYDEBUG(681, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1133 "Zend/zend_language_scanner.l" +#line 1131 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FUNCTION); } -#line 6670 "Zend/zend_language_scanner.c" +#line 6668 "Zend/zend_language_scanner.c" yy682: YYDEBUG(682, *YYCURSOR); yych = *++YYCURSOR; @@ -6734,11 +6732,11 @@ yy692: } YYDEBUG(693, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1768 "Zend/zend_language_scanner.l" +#line 1766 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FILE); } -#line 6742 "Zend/zend_language_scanner.c" +#line 6740 "Zend/zend_language_scanner.c" yy694: YYDEBUG(694, *YYCURSOR); yych = *++YYCURSOR; @@ -6759,11 +6757,11 @@ yy696: } YYDEBUG(697, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1764 "Zend/zend_language_scanner.l" +#line 1762 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LINE); } -#line 6767 "Zend/zend_language_scanner.c" +#line 6765 "Zend/zend_language_scanner.c" yy698: YYDEBUG(698, *YYCURSOR); yych = *++YYCURSOR; @@ -6800,11 +6798,11 @@ yy703: } YYDEBUG(704, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1235 "Zend/zend_language_scanner.l" +#line 1233 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDSWITCH); } -#line 6808 "Zend/zend_language_scanner.c" +#line 6806 "Zend/zend_language_scanner.c" yy705: YYDEBUG(705, *YYCURSOR); yych = *++YYCURSOR; @@ -6831,11 +6829,11 @@ yy708: } YYDEBUG(709, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1397 "Zend/zend_language_scanner.l" +#line 1395 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INSTEADOF); } -#line 6839 "Zend/zend_language_scanner.c" +#line 6837 "Zend/zend_language_scanner.c" yy710: YYDEBUG(710, *YYCURSOR); ++YYCURSOR; @@ -6844,11 +6842,11 @@ yy710: } YYDEBUG(711, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1271 "Zend/zend_language_scanner.l" +#line 1269 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INTERFACE); } -#line 6852 "Zend/zend_language_scanner.c" +#line 6850 "Zend/zend_language_scanner.c" yy712: YYDEBUG(712, *YYCURSOR); ++YYCURSOR; @@ -6857,11 +6855,11 @@ yy712: } YYDEBUG(713, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1389 "Zend/zend_language_scanner.l" +#line 1387 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NAMESPACE); } -#line 6865 "Zend/zend_language_scanner.c" +#line 6863 "Zend/zend_language_scanner.c" yy714: YYDEBUG(714, *YYCURSOR); ++YYCURSOR; @@ -6870,11 +6868,11 @@ yy714: } YYDEBUG(715, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1433 "Zend/zend_language_scanner.l" +#line 1431 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PROTECTED); } -#line 6878 "Zend/zend_language_scanner.c" +#line 6876 "Zend/zend_language_scanner.c" yy716: YYDEBUG(716, *YYCURSOR); yych = *++YYCURSOR; @@ -6895,11 +6893,11 @@ yy718: } YYDEBUG(719, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1748 "Zend/zend_language_scanner.l" +#line 1746 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CLASS_C); } -#line 6903 "Zend/zend_language_scanner.c" +#line 6901 "Zend/zend_language_scanner.c" yy720: YYDEBUG(720, *YYCURSOR); yych = *++YYCURSOR; @@ -6931,11 +6929,11 @@ yy724: } YYDEBUG(725, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1752 "Zend/zend_language_scanner.l" +#line 1750 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_TRAIT_C); } -#line 6939 "Zend/zend_language_scanner.c" +#line 6937 "Zend/zend_language_scanner.c" yy726: YYDEBUG(726, *YYCURSOR); ++YYCURSOR; @@ -6944,11 +6942,11 @@ yy726: } YYDEBUG(727, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1219 "Zend/zend_language_scanner.l" +#line 1217 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDDECLARE); } -#line 6952 "Zend/zend_language_scanner.c" +#line 6950 "Zend/zend_language_scanner.c" yy728: YYDEBUG(728, *YYCURSOR); ++YYCURSOR; @@ -6957,11 +6955,11 @@ yy728: } YYDEBUG(729, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1211 "Zend/zend_language_scanner.l" +#line 1209 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDFOREACH); } -#line 6965 "Zend/zend_language_scanner.c" +#line 6963 "Zend/zend_language_scanner.c" yy730: YYDEBUG(730, *YYCURSOR); ++YYCURSOR; @@ -6970,11 +6968,11 @@ yy730: } YYDEBUG(731, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1283 "Zend/zend_language_scanner.l" +#line 1281 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IMPLEMENTS); } -#line 6978 "Zend/zend_language_scanner.c" +#line 6976 "Zend/zend_language_scanner.c" yy732: YYDEBUG(732, *YYCURSOR); yych = *++YYCURSOR; @@ -6989,11 +6987,11 @@ yy733: } YYDEBUG(734, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1223 "Zend/zend_language_scanner.l" +#line 1221 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INSTANCEOF); } -#line 6997 "Zend/zend_language_scanner.c" +#line 6995 "Zend/zend_language_scanner.c" yy735: YYDEBUG(735, *YYCURSOR); yych = *++YYCURSOR; @@ -7041,11 +7039,11 @@ yy739: } YYDEBUG(740, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1760 "Zend/zend_language_scanner.l" +#line 1758 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_METHOD_C); } -#line 7049 "Zend/zend_language_scanner.c" +#line 7047 "Zend/zend_language_scanner.c" yy741: YYDEBUG(741, *YYCURSOR); yych = *++YYCURSOR; @@ -7069,13 +7067,13 @@ yy744: ++YYCURSOR; YYDEBUG(745, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1145 "Zend/zend_language_scanner.l" +#line 1143 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); HANDLE_NEWLINES(yytext, yyleng); RETURN_TOKEN(T_YIELD_FROM); } -#line 7079 "Zend/zend_language_scanner.c" +#line 7077 "Zend/zend_language_scanner.c" yy746: YYDEBUG(746, *YYCURSOR); yych = *++YYCURSOR; @@ -7100,11 +7098,11 @@ yy749: } YYDEBUG(750, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1377 "Zend/zend_language_scanner.l" +#line 1375 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INCLUDE_ONCE); } -#line 7108 "Zend/zend_language_scanner.c" +#line 7106 "Zend/zend_language_scanner.c" yy751: YYDEBUG(751, *YYCURSOR); ++YYCURSOR; @@ -7113,11 +7111,11 @@ yy751: } YYDEBUG(752, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1385 "Zend/zend_language_scanner.l" +#line 1383 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_REQUIRE_ONCE); } -#line 7121 "Zend/zend_language_scanner.c" +#line 7119 "Zend/zend_language_scanner.c" yy753: YYDEBUG(753, *YYCURSOR); ++YYCURSOR; @@ -7126,11 +7124,11 @@ yy753: } YYDEBUG(754, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1756 "Zend/zend_language_scanner.l" +#line 1754 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FUNC_C); } -#line 7134 "Zend/zend_language_scanner.c" +#line 7132 "Zend/zend_language_scanner.c" yy755: YYDEBUG(755, *YYCURSOR); yych = *++YYCURSOR; @@ -7156,11 +7154,11 @@ yy758: } YYDEBUG(759, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1776 "Zend/zend_language_scanner.l" +#line 1774 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NS_C); } -#line 7164 "Zend/zend_language_scanner.c" +#line 7162 "Zend/zend_language_scanner.c" yy760: YYDEBUG(760, *YYCURSOR); yych = *++YYCURSOR; @@ -7174,11 +7172,11 @@ yy761: } YYDEBUG(762, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1413 "Zend/zend_language_scanner.l" +#line 1411 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_HALT_COMPILER); } -#line 7182 "Zend/zend_language_scanner.c" +#line 7180 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_LOOKING_FOR_PROPERTY: @@ -7244,13 +7242,13 @@ yy765: yy766: YYDEBUG(766, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1307 "Zend/zend_language_scanner.l" +#line 1305 "Zend/zend_language_scanner.l" { yyless(0); yy_pop_state(); goto restart; } -#line 7254 "Zend/zend_language_scanner.c" +#line 7252 "Zend/zend_language_scanner.c" yy767: YYDEBUG(767, *YYCURSOR); ++YYCURSOR; @@ -7262,12 +7260,12 @@ yy767: } YYDEBUG(769, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1292 "Zend/zend_language_scanner.l" +#line 1290 "Zend/zend_language_scanner.l" { HANDLE_NEWLINES(yytext, yyleng); RETURN_TOKEN(T_WHITESPACE); } -#line 7271 "Zend/zend_language_scanner.c" +#line 7269 "Zend/zend_language_scanner.c" yy770: YYDEBUG(770, *YYCURSOR); yych = *++YYCURSOR; @@ -7284,23 +7282,23 @@ yy771: } YYDEBUG(773, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1301 "Zend/zend_language_scanner.l" +#line 1299 "Zend/zend_language_scanner.l" { yy_pop_state(); zend_copy_value(zendlval, yytext, yyleng); RETURN_TOKEN(T_STRING); } -#line 7294 "Zend/zend_language_scanner.c" +#line 7292 "Zend/zend_language_scanner.c" yy774: YYDEBUG(774, *YYCURSOR); ++YYCURSOR; YYDEBUG(775, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1297 "Zend/zend_language_scanner.l" +#line 1295 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_OBJECT_OPERATOR); } -#line 7304 "Zend/zend_language_scanner.c" +#line 7302 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_LOOKING_FOR_VARNAME: @@ -7357,14 +7355,14 @@ yy778: yy779: YYDEBUG(779, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1612 "Zend/zend_language_scanner.l" +#line 1610 "Zend/zend_language_scanner.l" { yyless(0); yy_pop_state(); yy_push_state(ST_IN_SCRIPTING); goto restart; } -#line 7368 "Zend/zend_language_scanner.c" +#line 7366 "Zend/zend_language_scanner.c" yy780: YYDEBUG(780, *YYCURSOR); yych = *(YYMARKER = ++YYCURSOR); @@ -7411,7 +7409,7 @@ yy784: ++YYCURSOR; YYDEBUG(785, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1603 "Zend/zend_language_scanner.l" +#line 1601 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); zend_copy_value(zendlval, yytext, yyleng); @@ -7419,7 +7417,7 @@ yy784: yy_push_state(ST_IN_SCRIPTING); RETURN_TOKEN(T_STRING_VARNAME); } -#line 7423 "Zend/zend_language_scanner.c" +#line 7421 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_NOWDOC: @@ -7430,7 +7428,7 @@ yyc_ST_NOWDOC: ++YYCURSOR; YYDEBUG(789, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2332 "Zend/zend_language_scanner.l" +#line 2330 "Zend/zend_language_scanner.l" { int newline = 0; @@ -7486,7 +7484,7 @@ nowdoc_scan_done: HANDLE_NEWLINES(yytext, yyleng - newline); RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE); } -#line 7490 "Zend/zend_language_scanner.c" +#line 7488 "Zend/zend_language_scanner.c" /* *********************************** */ yyc_ST_VAR_OFFSET: { @@ -7574,7 +7572,7 @@ yy792: ++YYCURSOR; YYDEBUG(793, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2389 "Zend/zend_language_scanner.l" +#line 2387 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -7583,13 +7581,13 @@ yy792: zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE); goto restart; } -#line 7587 "Zend/zend_language_scanner.c" +#line 7585 "Zend/zend_language_scanner.c" yy794: YYDEBUG(794, *YYCURSOR); ++YYCURSOR; YYDEBUG(795, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1883 "Zend/zend_language_scanner.l" +#line 1881 "Zend/zend_language_scanner.l" { /* Invalid rule to return a more explicit parse error with proper line number */ yyless(0); @@ -7597,19 +7595,19 @@ yy794: ZVAL_NULL(zendlval); RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE); } -#line 7601 "Zend/zend_language_scanner.c" +#line 7599 "Zend/zend_language_scanner.c" yy796: YYDEBUG(796, *YYCURSOR); ++YYCURSOR; yy797: YYDEBUG(797, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1878 "Zend/zend_language_scanner.l" +#line 1876 "Zend/zend_language_scanner.l" { /* Only '[' or '-' can be valid, but returning other tokens will allow a more explicit parse error */ RETURN_TOKEN(yytext[0]); } -#line 7613 "Zend/zend_language_scanner.c" +#line 7611 "Zend/zend_language_scanner.c" yy798: YYDEBUG(798, *YYCURSOR); yych = *++YYCURSOR; @@ -7644,7 +7642,7 @@ yy799: yy800: YYDEBUG(800, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1718 "Zend/zend_language_scanner.l" +#line 1716 "Zend/zend_language_scanner.l" { /* Offset could be treated as a long */ if (yyleng < MAX_LENGTH_OF_LONG - 1 || (yyleng == MAX_LENGTH_OF_LONG - 1 && strcmp(yytext, long_min_digits) < 0)) { char *end; @@ -7660,7 +7658,7 @@ string: } RETURN_TOKEN(T_NUM_STRING); } -#line 7664 "Zend/zend_language_scanner.c" +#line 7662 "Zend/zend_language_scanner.c" yy801: YYDEBUG(801, *YYCURSOR); ++YYCURSOR; @@ -7682,23 +7680,23 @@ yy803: } YYDEBUG(805, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1891 "Zend/zend_language_scanner.l" +#line 1889 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, yytext, yyleng); RETURN_TOKEN(T_STRING); } -#line 7691 "Zend/zend_language_scanner.c" +#line 7689 "Zend/zend_language_scanner.c" yy806: YYDEBUG(806, *YYCURSOR); ++YYCURSOR; YYDEBUG(807, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1873 "Zend/zend_language_scanner.l" +#line 1871 "Zend/zend_language_scanner.l" { yy_pop_state(); RETURN_TOKEN(']'); } -#line 7702 "Zend/zend_language_scanner.c" +#line 7700 "Zend/zend_language_scanner.c" yy808: YYDEBUG(808, *YYCURSOR); ++YYCURSOR; @@ -7723,12 +7721,12 @@ yy808: yy810: YYDEBUG(810, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1868 "Zend/zend_language_scanner.l" +#line 1866 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 7732 "Zend/zend_language_scanner.c" +#line 7730 "Zend/zend_language_scanner.c" yy811: YYDEBUG(811, *YYCURSOR); ++YYCURSOR; @@ -7740,12 +7738,12 @@ yy811: yy813: YYDEBUG(813, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1734 "Zend/zend_language_scanner.l" +#line 1732 "Zend/zend_language_scanner.l" { /* Offset must be treated as a string */ ZVAL_STRINGL(zendlval, yytext, yyleng); RETURN_TOKEN(T_NUM_STRING); } -#line 7749 "Zend/zend_language_scanner.c" +#line 7747 "Zend/zend_language_scanner.c" yy814: YYDEBUG(814, *YYCURSOR); yych = *++YYCURSOR; @@ -7785,6 +7783,6 @@ yy819: goto yy813; } } -#line 2398 "Zend/zend_language_scanner.l" +#line 2396 "Zend/zend_language_scanner.l" } diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index aafca1682d..46bb957660 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -648,9 +648,7 @@ zend_op_array *compile_filename(int type, zval *filename) zend_string *opened_path = NULL; if (Z_TYPE_P(filename) != IS_STRING) { - tmp = *filename; - zval_copy_ctor(&tmp); - convert_to_string(&tmp); + ZVAL_STR(&tmp, zval_get_string(filename)); filename = &tmp; } file_handle.filename = Z_STRVAL_P(filename); diff --git a/Zend/zend_list.c b/Zend/zend_list.c index c816b94b61..1e86a58542 100644 --- a/Zend/zend_list.c +++ b/Zend/zend_list.c @@ -31,7 +31,7 @@ ZEND_API int le_index_ptr; /* true global */ static HashTable list_destructors; -ZEND_API zval *zend_list_insert(void *ptr, int type) +ZEND_API zval* ZEND_FASTCALL zend_list_insert(void *ptr, int type) { int index; zval zv; @@ -44,16 +44,16 @@ ZEND_API zval *zend_list_insert(void *ptr, int type) return zend_hash_index_add_new(&EG(regular_list), index, &zv); } -ZEND_API int zend_list_delete(zend_resource *res) +ZEND_API int ZEND_FASTCALL zend_list_delete(zend_resource *res) { - if (--GC_REFCOUNT(res) <= 0) { + if (GC_DELREF(res) <= 0) { return zend_hash_index_del(&EG(regular_list), res->handle); } else { return SUCCESS; } } -ZEND_API int zend_list_free(zend_resource *res) +ZEND_API int ZEND_FASTCALL zend_list_free(zend_resource *res) { if (GC_REFCOUNT(res) <= 0) { return zend_hash_index_del(&EG(regular_list), res->handle); @@ -81,7 +81,7 @@ static void zend_resource_dtor(zend_resource *res) } -ZEND_API int zend_list_close(zend_resource *res) +ZEND_API int ZEND_FASTCALL zend_list_close(zend_resource *res) { if (GC_REFCOUNT(res) <= 0) { return zend_list_free(res); @@ -337,6 +337,33 @@ const char *zend_rsrc_list_get_rsrc_type(zend_resource *res) } } +ZEND_API zend_resource* zend_register_persistent_resource_ex(zend_string *key, void *rsrc_pointer, int rsrc_type) +{ + zval *zv; + zval tmp; + + ZVAL_NEW_PERSISTENT_RES(&tmp, -1, rsrc_pointer, rsrc_type); + GC_MAKE_PERSISTENT_LOCAL(Z_COUNTED(tmp)); + GC_MAKE_PERSISTENT_LOCAL(key); + + zv = zend_hash_update(&EG(persistent_list), key, &tmp); + if (UNEXPECTED(zv == NULL)) { + free(Z_RES(tmp)); + return NULL; + } + + return Z_RES_P(zv); +} + +ZEND_API zend_resource* zend_register_persistent_resource(const char *key, size_t key_len, void *rsrc_pointer, int rsrc_type) +{ + zend_string *str = zend_string_init(key, key_len, 1); + zend_resource *ret = zend_register_persistent_resource_ex(str, rsrc_pointer, rsrc_type); + + zend_string_release(str); + return ret; +} + /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_list.h b/Zend/zend_list.h index 2d6535c805..bad9ad4b3b 100644 --- a/Zend/zend_list.h +++ b/Zend/zend_list.h @@ -54,10 +54,10 @@ void zend_destroy_rsrc_list(HashTable *ht); int zend_init_rsrc_list_dtors(void); void zend_destroy_rsrc_list_dtors(void); -ZEND_API zval *zend_list_insert(void *ptr, int type); -ZEND_API int zend_list_free(zend_resource *res); -ZEND_API int zend_list_delete(zend_resource *res); -ZEND_API int zend_list_close(zend_resource *res); +ZEND_API zval* ZEND_FASTCALL zend_list_insert(void *ptr, int type); +ZEND_API int ZEND_FASTCALL zend_list_free(zend_resource *res); +ZEND_API int ZEND_FASTCALL zend_list_delete(zend_resource *res); +ZEND_API int ZEND_FASTCALL zend_list_close(zend_resource *res); ZEND_API zend_resource *zend_register_resource(void *rsrc_pointer, int rsrc_type); ZEND_API void *zend_fetch_resource(zend_resource *res, const char *resource_type_name, int resource_type); @@ -68,6 +68,9 @@ ZEND_API void *zend_fetch_resource2_ex(zval *res, const char *resource_type_name ZEND_API const char *zend_rsrc_list_get_rsrc_type(zend_resource *res); ZEND_API int zend_fetch_list_dtor_id(const char *type_name); +ZEND_API zend_resource* zend_register_persistent_resource(const char *key, size_t key_len, void *rsrc_pointer, int rsrc_type); +ZEND_API zend_resource* zend_register_persistent_resource_ex(zend_string *key, void *rsrc_pointer, int rsrc_type); + extern ZEND_API int le_index_ptr; /* list entry type for index pointers */ END_EXTERN_C() diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c index 7d9b501da1..4dd14775b3 100644 --- a/Zend/zend_llist.c +++ b/Zend/zend_llist.c @@ -200,7 +200,7 @@ ZEND_API void zend_llist_sort(zend_llist *l, llist_compare_func_t comp_func) zend_llist_element **elements; zend_llist_element *element, **ptr; - if (l->count <= 0) { + if (l->count == 0) { return; } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 43b6579273..51ec12352f 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -35,24 +35,14 @@ #define DEBUG_OBJECT_HANDLERS 0 +#define ZEND_WRONG_PROPERTY_OFFSET 0 + /* guard flags */ #define IN_GET (1<<0) #define IN_SET (1<<1) #define IN_UNSET (1<<2) #define IN_ISSET (1<<3) -#define Z_OBJ_PROTECT_RECURSION(zval_p) \ - do { \ - if (Z_OBJ_APPLY_COUNT_P(zval_p) >= 3) { \ - zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?"); \ - } \ - Z_OBJ_INC_APPLY_COUNT_P(zval_p); \ - } while (0) - - -#define Z_OBJ_UNPROTECT_RECURSION(zval_p) \ - Z_OBJ_DEC_APPLY_COUNT_P(zval_p) - /* __X accessors explanation: @@ -76,8 +66,7 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */ zend_property_info *prop_info; zend_class_entry *ce = zobj->ce; - ALLOC_HASHTABLE(zobj->properties); - zend_hash_init(zobj->properties, ce->default_properties_count, NULL, ZVAL_PTR_DTOR, 0); + zobj->properties = zend_new_array(ce->default_properties_count); if (ce->default_properties_count) { zend_hash_real_init(zobj->properties, 0); zobj->properties->nInternalPointer = 0; @@ -177,8 +166,7 @@ ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp) /* {{{ * } } else if (Z_TYPE(retval) == IS_NULL) { *is_temp = 1; - ALLOC_HASHTABLE(ht); - zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0); + ht = zend_new_array(0); return ht; } @@ -234,12 +222,8 @@ static void zend_std_call_unsetter(zval *object, zval *member) /* {{{ */ property name */ - if (Z_REFCOUNTED_P(member)) Z_ADDREF_P(member); - zend_call_method_with_1_params(object, ce, &ce->__unset, ZEND_UNSET_FUNC_NAME, NULL, member); - zval_ptr_dtor(member); - EG(fake_scope) = orig_fake_scope; } /* }}} */ @@ -257,12 +241,8 @@ static void zend_std_call_issetter(zval *object, zval *member, zval *retval) /* it should return whether the property is set or not */ - if (Z_REFCOUNTED_P(member)) Z_ADDREF_P(member); - zend_call_method_with_1_params(object, ce, &ce->__isset, ZEND_ISSET_FUNC_NAME, retval, member); - zval_ptr_dtor(member); - EG(fake_scope) = orig_fake_scope; } /* }}} */ @@ -306,7 +286,7 @@ static zend_always_inline zend_bool is_derived_class(zend_class_entry *child_cla } /* }}} */ -static zend_always_inline uint32_t zend_get_property_offset(zend_class_entry *ce, zend_string *member, int silent, void **cache_slot) /* {{{ */ +static zend_always_inline uintptr_t zend_get_property_offset(zend_class_entry *ce, zend_string *member, int silent, void **cache_slot) /* {{{ */ { zval *zv; zend_property_info *property_info = NULL; @@ -314,7 +294,7 @@ static zend_always_inline uint32_t zend_get_property_offset(zend_class_entry *ce zend_class_entry *scope; if (cache_slot && EXPECTED(ce == CACHED_PTR_EX(cache_slot))) { - return (uint32_t)(intptr_t)CACHED_PTR_EX(cache_slot + 1); + return (uintptr_t)CACHED_PTR_EX(cache_slot + 1); } if (UNEXPECTED(ZSTR_VAL(member)[0] == '\0' && ZSTR_LEN(member) != 0)) { @@ -372,7 +352,7 @@ static zend_always_inline uint32_t zend_get_property_offset(zend_class_entry *ce } else if (UNEXPECTED(property_info == NULL)) { exit_dynamic: if (cache_slot) { - CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, (void*)(intptr_t)ZEND_DYNAMIC_PROPERTY_OFFSET); + CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); } return ZEND_DYNAMIC_PROPERTY_OFFSET; } else if (UNEXPECTED(property_info == ZEND_WRONG_PROPERTY_INFO)) { @@ -385,7 +365,7 @@ exit_dynamic: exit: if (cache_slot) { - CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, (void*)(intptr_t)property_info->offset); + CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, (void*)(uintptr_t)property_info->offset); } return property_info->offset; } @@ -522,8 +502,7 @@ ZEND_API uint32_t *zend_get_property_guard(zend_object *zobj, zend_string *membe if (EXPECTED(str == member) || /* hash values are always pred-calculated here */ (EXPECTED(ZSTR_H(str) == ZSTR_H(member)) && - EXPECTED(ZSTR_LEN(str) == ZSTR_LEN(member)) && - EXPECTED(memcmp(ZSTR_VAL(str), ZSTR_VAL(member), ZSTR_LEN(member)) == 0))) { + EXPECTED(zend_string_equal_content(str, member)))) { return &zv->u2.property_guard; } else if (EXPECTED(zv->u2.property_guard == 0)) { zend_string_release(Z_STR_P(zv)); @@ -564,14 +543,14 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_ zend_object *zobj; zval tmp_member, tmp_object; zval *retval; - uint32_t property_offset; + uintptr_t property_offset; uint32_t *guard = NULL; zobj = Z_OBJ_P(object); ZVAL_UNDEF(&tmp_member); if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) { - ZVAL_STR(&tmp_member, zval_get_string(member)); + ZVAL_STR(&tmp_member, zval_get_string_func(member)); member = &tmp_member; cache_slot = NULL; } @@ -583,15 +562,38 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_ /* make zend_get_property_info silent if we have getter - we may want to use it */ property_offset = zend_get_property_offset(zobj->ce, Z_STR_P(member), (type == BP_VAR_IS) || (zobj->ce->__get != NULL), cache_slot); - if (EXPECTED(property_offset != ZEND_WRONG_PROPERTY_OFFSET)) { - if (EXPECTED(property_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, property_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - goto exit; + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) { + retval = OBJ_PROP(zobj, property_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + goto exit; + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(property_offset))) { + if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(property_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(property_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(member)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(member))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(member)))))) { + retval = &p->val; + goto exit; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); } - } else if (EXPECTED(zobj->properties != NULL)) { retval = zend_hash_find(zobj->properties, Z_STR_P(member)); - if (EXPECTED(retval)) goto exit; + if (EXPECTED(retval)) { + if (cache_slot) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + } + goto exit; + } } } else if (UNEXPECTED(EG(exception))) { retval = &EG(uninitialized_zval); @@ -646,7 +648,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_ retval = rv; if (!Z_ISREF_P(rv) && (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)) { - SEPARATE_ZVAL(rv); + SEPARATE_ZVAL_NOREF(rv); if (UNEXPECTED(Z_TYPE_P(rv) != IS_OBJECT)) { zend_error(E_NOTICE, "Indirect modification of overloaded property %s::$%s has no effect", ZSTR_VAL(zobj->ce->name), Z_STRVAL_P(member)); } @@ -685,29 +687,29 @@ ZEND_API void zend_std_write_property(zval *object, zval *member, zval *value, v zend_object *zobj; zval tmp_member; zval *variable_ptr; - uint32_t property_offset; + uintptr_t property_offset; zobj = Z_OBJ_P(object); ZVAL_UNDEF(&tmp_member); if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) { - ZVAL_STR(&tmp_member, zval_get_string(member)); + ZVAL_STR(&tmp_member, zval_get_string_func(member)); member = &tmp_member; cache_slot = NULL; } property_offset = zend_get_property_offset(zobj->ce, Z_STR_P(member), (zobj->ce->__set != NULL), cache_slot); - if (EXPECTED(property_offset != ZEND_WRONG_PROPERTY_OFFSET)) { - if (EXPECTED(property_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { - variable_ptr = OBJ_PROP(zobj, property_offset); - if (Z_TYPE_P(variable_ptr) != IS_UNDEF) { - goto found; - } - } else if (EXPECTED(zobj->properties != NULL)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) { + variable_ptr = OBJ_PROP(zobj, property_offset); + if (Z_TYPE_P(variable_ptr) != IS_UNDEF) { + goto found; + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(property_offset))) { + if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } @@ -733,7 +735,7 @@ found: zend_std_call_setter(&tmp_object, member, value); (*guard) &= ~IN_SET; zval_ptr_dtor(&tmp_object); - } else if (EXPECTED(property_offset != ZEND_WRONG_PROPERTY_OFFSET)) { + } else if (EXPECTED(!IS_WRONG_PROPERTY_OFFSET(property_offset))) { goto write_std_property; } else { if (Z_STRVAL_P(member)[0] == '\0' && Z_STRLEN_P(member) != 0) { @@ -741,7 +743,7 @@ found: goto exit; } } - } else if (EXPECTED(property_offset != ZEND_WRONG_PROPERTY_OFFSET)) { + } else if (EXPECTED(!IS_WRONG_PROPERTY_OFFSET(property_offset))) { zval tmp; write_std_property: @@ -754,7 +756,7 @@ write_std_property: Z_ADDREF_P(value); } } - if (EXPECTED(property_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) { ZVAL_COPY_VALUE(OBJ_PROP(zobj, property_offset), value); } else { if (!zobj->properties) { @@ -880,16 +882,12 @@ static int zend_std_has_dimension(zval *object, zval *offset, int check_empty) / static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type, void **cache_slot) /* {{{ */ { zend_object *zobj; - zend_string *name; + zend_string *name, *tmp_name; zval *retval = NULL; - uint32_t property_offset; + uintptr_t property_offset; zobj = Z_OBJ_P(object); - if (EXPECTED(Z_TYPE_P(member) == IS_STRING)) { - name = Z_STR_P(member); - } else { - name = zval_get_string(member); - } + name = zval_get_tmp_string(member, &tmp_name); #if DEBUG_OBJECT_HANDLERS fprintf(stderr, "Ptr object #%d property: %s\n", Z_OBJ_HANDLE_P(object), ZSTR_VAL(name)); @@ -897,56 +895,50 @@ static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type, property_offset = zend_get_property_offset(zobj->ce, name, (zobj->ce->__get != NULL), cache_slot); - if (EXPECTED(property_offset != ZEND_WRONG_PROPERTY_OFFSET)) { - if (EXPECTED(property_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, property_offset); - if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) { - if (EXPECTED(!zobj->ce->__get) || - UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET)) { - ZVAL_NULL(retval); - /* Notice is thrown after creation of the property, to avoid EG(std_property_info) - * being overwritten in an error handler. */ - if (UNEXPECTED(type == BP_VAR_RW || type == BP_VAR_R)) { - zend_error(E_NOTICE, "Undefined property: %s::$%s", ZSTR_VAL(zobj->ce->name), ZSTR_VAL(name)); - } - } else { - /* we do have getter - fail and let it try again with usual get/set */ - retval = NULL; - } - } - } else { - if (EXPECTED(zobj->properties)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; - } - zobj->properties = zend_array_dup(zobj->properties); - } - if (EXPECTED((retval = zend_hash_find(zobj->properties, name)) != NULL)) { - if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) { - zend_string_release(name); - } - return retval; - } - } + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) { + retval = OBJ_PROP(zobj, property_offset); + if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) { if (EXPECTED(!zobj->ce->__get) || UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET)) { - if (UNEXPECTED(!zobj->properties)) { - rebuild_object_properties(zobj); - } - retval = zend_hash_update(zobj->properties, name, &EG(uninitialized_zval)); + ZVAL_NULL(retval); /* Notice is thrown after creation of the property, to avoid EG(std_property_info) * being overwritten in an error handler. */ if (UNEXPECTED(type == BP_VAR_RW || type == BP_VAR_R)) { zend_error(E_NOTICE, "Undefined property: %s::$%s", ZSTR_VAL(zobj->ce->name), ZSTR_VAL(name)); } + } else { + /* we do have getter - fail and let it try again with usual get/set */ + retval = NULL; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(property_offset))) { + if (EXPECTED(zobj->properties)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + if (EXPECTED((retval = zend_hash_find(zobj->properties, name)) != NULL)) { + zend_tmp_string_release(tmp_name); + return retval; + } + } + if (EXPECTED(!zobj->ce->__get) || + UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET)) { + if (UNEXPECTED(!zobj->properties)) { + rebuild_object_properties(zobj); + } + retval = zend_hash_update(zobj->properties, name, &EG(uninitialized_zval)); + /* Notice is thrown after creation of the property, to avoid EG(std_property_info) + * being overwritten in an error handler. */ + if (UNEXPECTED(type == BP_VAR_RW || type == BP_VAR_R)) { + zend_error(E_NOTICE, "Undefined property: %s::$%s", ZSTR_VAL(zobj->ce->name), ZSTR_VAL(name)); } } } - if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) { - zend_string_release(name); - } + zend_tmp_string_release(tmp_name); return retval; } /* }}} */ @@ -955,41 +947,40 @@ static void zend_std_unset_property(zval *object, zval *member, void **cache_slo { zend_object *zobj; zval tmp_member; - uint32_t property_offset; + uintptr_t property_offset; zobj = Z_OBJ_P(object); ZVAL_UNDEF(&tmp_member); if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) { - ZVAL_STR(&tmp_member, zval_get_string(member)); + ZVAL_STR(&tmp_member, zval_get_string_func(member)); member = &tmp_member; cache_slot = NULL; } property_offset = zend_get_property_offset(zobj->ce, Z_STR_P(member), (zobj->ce->__unset != NULL), cache_slot); - if (EXPECTED(property_offset != ZEND_WRONG_PROPERTY_OFFSET)) { - if (EXPECTED(property_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { - zval *slot = OBJ_PROP(zobj, property_offset); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) { + zval *slot = OBJ_PROP(zobj, property_offset); - if (Z_TYPE_P(slot) != IS_UNDEF) { - zval_ptr_dtor(slot); - ZVAL_UNDEF(slot); - if (zobj->properties) { - zobj->properties->u.v.flags |= HASH_FLAG_HAS_EMPTY_IND; - } - goto exit; - } - } else if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; - } - zobj->properties = zend_array_dup(zobj->properties); + if (Z_TYPE_P(slot) != IS_UNDEF) { + zval_ptr_dtor(slot); + ZVAL_UNDEF(slot); + if (zobj->properties) { + zobj->properties->u.v.flags |= HASH_FLAG_HAS_EMPTY_IND; } - if (EXPECTED(zend_hash_del(zobj->properties, Z_STR_P(member)) != FAILURE)) { - goto exit; + goto exit; + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(property_offset)) + && EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); } + zobj->properties = zend_array_dup(zobj->properties); + } + if (EXPECTED(zend_hash_del(zobj->properties, Z_STR_P(member)) != FAILURE)) { + goto exit; } } else if (UNEXPECTED(EG(exception))) { goto exit; @@ -1469,6 +1460,9 @@ static int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */ zobj1 = Z_OBJ_P(o1); zobj2 = Z_OBJ_P(o2); + if (zobj1 == zobj2) { + return 0; /* the same object */ + } if (zobj1->ce != zobj2->ce) { return 1; /* different classes */ } @@ -1481,40 +1475,43 @@ static int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */ p1 = zobj1->properties_table; p2 = zobj2->properties_table; end = p1 + zobj1->ce->default_properties_count; - Z_OBJ_PROTECT_RECURSION(o1); - Z_OBJ_PROTECT_RECURSION(o2); + + /* It's enough to protect only one of the objects. + * The second one may be referenced from the first and this may cause + * false recursion detection. + */ + /* use bitwise OR to make only one conditional jump */ + if (UNEXPECTED(Z_IS_RECURSIVE_P(o1))) { + zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?"); + } + Z_PROTECT_RECURSION_P(o1); do { if (Z_TYPE_P(p1) != IS_UNDEF) { if (Z_TYPE_P(p2) != IS_UNDEF) { zval result; if (compare_function(&result, p1, p2)==FAILURE) { - Z_OBJ_UNPROTECT_RECURSION(o1); - Z_OBJ_UNPROTECT_RECURSION(o2); + Z_UNPROTECT_RECURSION_P(o1); return 1; } if (Z_LVAL(result) != 0) { - Z_OBJ_UNPROTECT_RECURSION(o1); - Z_OBJ_UNPROTECT_RECURSION(o2); + Z_UNPROTECT_RECURSION_P(o1); return Z_LVAL(result); } } else { - Z_OBJ_UNPROTECT_RECURSION(o1); - Z_OBJ_UNPROTECT_RECURSION(o2); + Z_UNPROTECT_RECURSION_P(o1); return 1; } } else { if (Z_TYPE_P(p2) != IS_UNDEF) { - Z_OBJ_UNPROTECT_RECURSION(o1); - Z_OBJ_UNPROTECT_RECURSION(o2); + Z_UNPROTECT_RECURSION_P(o1); return 1; } } p1++; p2++; } while (p1 != end); - Z_OBJ_UNPROTECT_RECURSION(o1); - Z_OBJ_UNPROTECT_RECURSION(o2); + Z_UNPROTECT_RECURSION_P(o1); return 0; } else { if (!zobj1->properties) { @@ -1534,41 +1531,64 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists, int result; zval *value = NULL; zval tmp_member; - uint32_t property_offset; + uintptr_t property_offset; zobj = Z_OBJ_P(object); ZVAL_UNDEF(&tmp_member); if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) { - ZVAL_STR(&tmp_member, zval_get_string(member)); + ZVAL_STR(&tmp_member, zval_get_string_func(member)); member = &tmp_member; cache_slot = NULL; } property_offset = zend_get_property_offset(zobj->ce, Z_STR_P(member), 1, cache_slot); - if (EXPECTED(property_offset != ZEND_WRONG_PROPERTY_OFFSET)) { - if (EXPECTED(property_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { - value = OBJ_PROP(zobj, property_offset); - if (Z_TYPE_P(value) != IS_UNDEF) { - goto found; + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(property_offset))) { + value = OBJ_PROP(zobj, property_offset); + if (Z_TYPE_P(value) != IS_UNDEF) { + goto found; + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(property_offset))) { + if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(property_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(property_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(member)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(member))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(member)))))) { + value = &p->val; + goto found; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); } - } else if (EXPECTED(zobj->properties != NULL) && - (value = zend_hash_find(zobj->properties, Z_STR_P(member))) != NULL) { + value = zend_hash_find(zobj->properties, Z_STR_P(member)); + if (value) { + if (cache_slot) { + uintptr_t idx = (char*)value - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + } found: - switch (has_set_exists) { - case 0: - ZVAL_DEREF(value); - result = (Z_TYPE_P(value) != IS_NULL); - break; - default: - result = zend_is_true(value); - break; - case 2: - result = 1; - break; + switch (has_set_exists) { + case 0: + ZVAL_DEREF(value); + result = (Z_TYPE_P(value) != IS_NULL); + break; + default: + result = zend_is_true(value); + break; + case 2: + result = 1; + break; + } + goto exit; } - goto exit; } } else if (UNEXPECTED(EG(exception))) { result = 0; @@ -1709,7 +1729,7 @@ int zend_std_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function **f ce = Z_OBJCE_P(obj); - if ((func = zend_hash_find(&ce->function_table, ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE))) == NULL) { + if ((func = zend_hash_find_ex(&ce->function_table, ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE), 1)) == NULL) { return FAILURE; } *fptr_ptr = Z_FUNC_P(func); diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 819185320f..29494d9006 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -25,10 +25,18 @@ struct _zend_property_info; #define ZEND_WRONG_PROPERTY_INFO \ - ((struct _zend_property_info*)((zend_intptr_t)-1)) + ((struct _zend_property_info*)((intptr_t)-1)) + +#define ZEND_DYNAMIC_PROPERTY_OFFSET ((uintptr_t)(intptr_t)(-1)) + +#define IS_VALID_PROPERTY_OFFSET(offset) ((intptr_t)(offset) > 0) +#define IS_WRONG_PROPERTY_OFFSET(offset) ((intptr_t)(offset) == 0) +#define IS_DYNAMIC_PROPERTY_OFFSET(offset) ((intptr_t)(offset) < 0) + +#define IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(offset) (offset == ZEND_DYNAMIC_PROPERTY_OFFSET) +#define ZEND_DECODE_DYN_PROP_OFFSET(offset) ((uintptr_t)(-(intptr_t)(offset) - 2)) +#define ZEND_ENCODE_DYN_PROP_OFFSET(offset) ((uintptr_t)(-((intptr_t)(offset) + 2))) -#define ZEND_DYNAMIC_PROPERTY_OFFSET ((uint32_t)(-1)) -#define ZEND_WRONG_PROPERTY_OFFSET ((uint32_t)(-2)) /* The following rule applies to read_property() and read_dimension() implementations: If you return a zval which is not otherwise referenced by the extension or the engine's diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index d5c375f6ed..642b9883a3 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -27,9 +27,9 @@ #include "zend_interfaces.h" #include "zend_exceptions.h" -ZEND_API void zend_object_std_init(zend_object *object, zend_class_entry *ce) +ZEND_API void ZEND_FASTCALL zend_object_std_init(zend_object *object, zend_class_entry *ce) { - GC_REFCOUNT(object) = 1; + GC_SET_REFCOUNT(object, 1); GC_TYPE_INFO(object) = IS_OBJECT | (GC_COLLECTABLE << GC_FLAGS_SHIFT); object->ce = ce; object->properties = NULL; @@ -46,7 +46,7 @@ ZEND_API void zend_object_std_dtor(zend_object *object) if (object->properties) { if (EXPECTED(!(GC_FLAGS(object->properties) & IS_ARRAY_IMMUTABLE))) { - if (EXPECTED(--GC_REFCOUNT(object->properties) == 0)) { + if (EXPECTED(GC_DELREF(object->properties) == 0)) { zend_array_destroy(object->properties); } } @@ -125,7 +125,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object) } } - GC_REFCOUNT(object)++; + GC_ADDREF(object); ZVAL_OBJ(&obj, object); /* Make sure that destructors are protected from previously thrown exceptions. @@ -156,7 +156,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object) } } -ZEND_API zend_object *zend_objects_new(zend_class_entry *ce) +ZEND_API zend_object* ZEND_FASTCALL zend_objects_new(zend_class_entry *ce) { zend_object *object = emalloc(sizeof(zend_object) + zend_object_properties_size(ce)); @@ -165,7 +165,7 @@ ZEND_API zend_object *zend_objects_new(zend_class_entry *ce) return object; } -ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *old_object) +ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, zend_object *old_object) { if (old_object->ce->default_properties_count) { zval *src = old_object->properties_table; @@ -183,7 +183,7 @@ ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *o /* fast copy */ if (EXPECTED(old_object->handlers == &std_object_handlers)) { if (EXPECTED(!(GC_FLAGS(old_object->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(old_object->properties)++; + GC_ADDREF(old_object->properties); } new_object->properties = old_object->properties; return; @@ -197,8 +197,7 @@ ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *o zend_string *key; if (!new_object->properties) { - ALLOC_HASHTABLE(new_object->properties); - zend_hash_init(new_object->properties, zend_hash_num_elements(old_object->properties), NULL, ZVAL_PTR_DTOR, 0); + new_object->properties = zend_new_array(zend_hash_num_elements(old_object->properties)); zend_hash_real_init(new_object->properties, 0); } else { zend_hash_extend(new_object->properties, new_object->properties->nNumUsed + zend_hash_num_elements(old_object->properties), 0); diff --git a/Zend/zend_objects.h b/Zend/zend_objects.h index 6bcb5fe922..42e659b6de 100644 --- a/Zend/zend_objects.h +++ b/Zend/zend_objects.h @@ -25,11 +25,12 @@ #include "zend.h" BEGIN_EXTERN_C() -ZEND_API void zend_object_std_init(zend_object *object, zend_class_entry *ce); +ZEND_API void ZEND_FASTCALL zend_object_std_init(zend_object *object, zend_class_entry *ce); +ZEND_API zend_object* ZEND_FASTCALL zend_objects_new(zend_class_entry *ce); +ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, zend_object *old_object); + ZEND_API void zend_object_std_dtor(zend_object *object); -ZEND_API zend_object *zend_objects_new(zend_class_entry *ce); ZEND_API void zend_objects_destroy_object(zend_object *object); -ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *old_object); ZEND_API zend_object *zend_objects_clone_obj(zval *object); END_EXTERN_C() diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c index d4de16fde1..1a5344dc40 100644 --- a/Zend/zend_objects_API.c +++ b/Zend/zend_objects_API.c @@ -26,7 +26,7 @@ #include "zend_API.h" #include "zend_objects_API.h" -ZEND_API void zend_objects_store_init(zend_objects_store *objects, uint32_t init_size) +ZEND_API void ZEND_FASTCALL zend_objects_store_init(zend_objects_store *objects, uint32_t init_size) { objects->object_buckets = (zend_object **) emalloc(init_size * sizeof(zend_object*)); objects->top = 1; /* Skip 0 so that handles are true */ @@ -35,13 +35,13 @@ ZEND_API void zend_objects_store_init(zend_objects_store *objects, uint32_t init memset(&objects->object_buckets[0], 0, sizeof(zend_object*)); } -ZEND_API void zend_objects_store_destroy(zend_objects_store *objects) +ZEND_API void ZEND_FASTCALL zend_objects_store_destroy(zend_objects_store *objects) { efree(objects->object_buckets); objects->object_buckets = NULL; } -ZEND_API void zend_objects_store_call_destructors(zend_objects_store *objects) +ZEND_API void ZEND_FASTCALL zend_objects_store_call_destructors(zend_objects_store *objects) { if (objects->top > 1) { uint32_t i; @@ -54,9 +54,9 @@ ZEND_API void zend_objects_store_call_destructors(zend_objects_store *objects) if (obj->handlers->dtor_obj && (obj->handlers->dtor_obj != zend_objects_destroy_object || obj->ce->destructor)) { - GC_REFCOUNT(obj)++; + GC_ADDREF(obj); obj->handlers->dtor_obj(obj); - GC_REFCOUNT(obj)--; + GC_DELREF(obj); } } } @@ -64,7 +64,7 @@ ZEND_API void zend_objects_store_call_destructors(zend_objects_store *objects) } } -ZEND_API void zend_objects_store_mark_destructed(zend_objects_store *objects) +ZEND_API void ZEND_FASTCALL zend_objects_store_mark_destructed(zend_objects_store *objects) { if (objects->object_buckets && objects->top > 1) { zend_object **obj_ptr = objects->object_buckets + 1; @@ -81,7 +81,7 @@ ZEND_API void zend_objects_store_mark_destructed(zend_objects_store *objects) } } -ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects, zend_bool fast_shutdown) +ZEND_API void ZEND_FASTCALL zend_objects_store_free_object_storage(zend_objects_store *objects, zend_bool fast_shutdown) { zend_object **obj_ptr, **end, *obj; @@ -101,9 +101,9 @@ ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects if (!(GC_FLAGS(obj) & IS_OBJ_FREE_CALLED)) { GC_FLAGS(obj) |= IS_OBJ_FREE_CALLED; if (obj->handlers->free_obj && obj->handlers->free_obj != zend_object_std_dtor) { - GC_REFCOUNT(obj)++; + GC_ADDREF(obj); obj->handlers->free_obj(obj); - GC_REFCOUNT(obj)--; + GC_DELREF(obj); } } } @@ -116,9 +116,9 @@ ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects if (!(GC_FLAGS(obj) & IS_OBJ_FREE_CALLED)) { GC_FLAGS(obj) |= IS_OBJ_FREE_CALLED; if (obj->handlers->free_obj) { - GC_REFCOUNT(obj)++; + GC_ADDREF(obj); obj->handlers->free_obj(obj); - GC_REFCOUNT(obj)--; + GC_DELREF(obj); } } } @@ -129,7 +129,7 @@ ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects /* Store objects API */ -ZEND_API void zend_objects_store_put(zend_object *object) +ZEND_API void ZEND_FASTCALL zend_objects_store_put(zend_object *object) { int handle; @@ -154,7 +154,7 @@ ZEND_API void zend_objects_store_put(zend_object *object) SET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[handle], EG(objects_store).free_list_head); \ EG(objects_store).free_list_head = handle; -ZEND_API void zend_objects_store_del(zend_object *object) /* {{{ */ +ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ */ { /* Make sure we hold a reference count during the destructor call otherwise, when the destructor ends the storage might be freed @@ -169,9 +169,9 @@ ZEND_API void zend_objects_store_del(zend_object *object) /* {{{ */ if (object->handlers->dtor_obj && (object->handlers->dtor_obj != zend_objects_destroy_object || object->ce->destructor)) { - GC_REFCOUNT(object)++; + GC_ADDREF(object); object->handlers->dtor_obj(object); - GC_REFCOUNT(object)--; + GC_DELREF(object); } } @@ -183,9 +183,9 @@ ZEND_API void zend_objects_store_del(zend_object *object) /* {{{ */ if (!(GC_FLAGS(object) & IS_OBJ_FREE_CALLED)) { GC_FLAGS(object) |= IS_OBJ_FREE_CALLED; if (object->handlers->free_obj) { - GC_REFCOUNT(object)++; + GC_ADDREF(object); object->handlers->free_obj(object); - GC_REFCOUNT(object)--; + GC_DELREF(object); } } ptr = ((char*)object) - object->handlers->offset; @@ -194,13 +194,13 @@ ZEND_API void zend_objects_store_del(zend_object *object) /* {{{ */ ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(handle); } } else { - GC_REFCOUNT(object)--; + GC_DELREF(object); } } } /* }}} */ -ZEND_API zend_object_handlers *zend_get_std_object_handlers(void) +ZEND_API zend_object_handlers* ZEND_FASTCALL zend_get_std_object_handlers(void) { return &std_object_handlers; } diff --git a/Zend/zend_objects_API.h b/Zend/zend_objects_API.h index c26284affe..edc8fba659 100644 --- a/Zend/zend_objects_API.h +++ b/Zend/zend_objects_API.h @@ -49,15 +49,15 @@ typedef struct _zend_objects_store { /* Global store handling functions */ BEGIN_EXTERN_C() -ZEND_API void zend_objects_store_init(zend_objects_store *objects, uint32_t init_size); -ZEND_API void zend_objects_store_call_destructors(zend_objects_store *objects); -ZEND_API void zend_objects_store_mark_destructed(zend_objects_store *objects); -ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects, zend_bool fast_shutdown); -ZEND_API void zend_objects_store_destroy(zend_objects_store *objects); +ZEND_API void ZEND_FASTCALL zend_objects_store_init(zend_objects_store *objects, uint32_t init_size); +ZEND_API void ZEND_FASTCALL zend_objects_store_call_destructors(zend_objects_store *objects); +ZEND_API void ZEND_FASTCALL zend_objects_store_mark_destructed(zend_objects_store *objects); +ZEND_API void ZEND_FASTCALL zend_objects_store_free_object_storage(zend_objects_store *objects, zend_bool fast_shutdown); +ZEND_API void ZEND_FASTCALL zend_objects_store_destroy(zend_objects_store *objects); /* Store API functions */ -ZEND_API void zend_objects_store_put(zend_object *object); -ZEND_API void zend_objects_store_del(zend_object *object); +ZEND_API void ZEND_FASTCALL zend_objects_store_put(zend_object *object); +ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object); /* Called when the ctor was terminated by an exception */ static zend_always_inline void zend_object_store_ctor_failed(zend_object *obj) @@ -67,12 +67,12 @@ static zend_always_inline void zend_object_store_ctor_failed(zend_object *obj) #define ZEND_OBJECTS_STORE_HANDLERS 0, zend_object_std_dtor, zend_objects_destroy_object, zend_objects_clone_obj -ZEND_API zend_object_handlers *zend_get_std_object_handlers(void); +ZEND_API zend_object_handlers * ZEND_FASTCALL zend_get_std_object_handlers(void); END_EXTERN_C() static zend_always_inline void zend_object_release(zend_object *obj) { - if (--GC_REFCOUNT(obj) == 0) { + if (GC_DELREF(obj) == 0) { zend_objects_store_del(obj); } else if (UNEXPECTED(GC_MAY_LEAK((zend_refcounted*)obj))) { gc_possible_root((zend_refcounted*)obj); @@ -86,6 +86,17 @@ static zend_always_inline size_t zend_object_properties_size(zend_class_entry *c ((ce->ce_flags & ZEND_ACC_USE_GUARDS) ? 0 : 1)); } +/* Allocates object type and zeros it, but not the properties. + * Properties MUST be initialized using object_properties_init(). */ +static zend_always_inline void *zend_object_alloc(size_t obj_size, zend_class_entry *ce) { + void *obj = emalloc(obj_size + zend_object_properties_size(ce)); + /* Subtraction of sizeof(zval) is necessary, because zend_object_properties_size() may be + * -sizeof(zval), if the object has no properties. */ + memset(obj, 0, obj_size - sizeof(zval)); + return obj; +} + + #endif /* ZEND_OBJECTS_H */ /* diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index e89a388037..3e01b3fc72 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -291,7 +291,7 @@ ZEND_API void destroy_zend_class(zval *zv) ZEND_HASH_FOREACH_PTR(&ce->constants_table, c) { if (c->ce == ce) { - zval_ptr_dtor(&c->value); + zval_ptr_dtor_nogc(&c->value); if (c->doc_comment) { zend_string_release(c->doc_comment); } @@ -346,10 +346,13 @@ ZEND_API void destroy_zend_class(zval *zv) zend_class_constant *c; ZEND_HASH_FOREACH_PTR(&ce->constants_table, c) { - zval_internal_ptr_dtor(&c->value); - if (c->doc_comment && c->ce == ce) { - zend_string_release(c->doc_comment); + if (c->ce == ce) { + zval_internal_ptr_dtor(&c->value); + if (c->doc_comment) { + zend_string_release(c->doc_comment); + } } + free(c); } ZEND_HASH_FOREACH_END(); zend_hash_destroy(&ce->constants_table); } @@ -376,7 +379,7 @@ ZEND_API void destroy_op_array(zend_op_array *op_array) if (op_array->static_variables && !(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) { - if (--GC_REFCOUNT(op_array->static_variables) == 0) { + if (GC_DELREF(op_array->static_variables) == 0) { zend_array_destroy(op_array->static_variables); } } @@ -407,7 +410,10 @@ ZEND_API void destroy_op_array(zend_op_array *op_array) zval_ptr_dtor_nogc(literal); literal++; } - efree(op_array->literals); + if (ZEND_USE_ABS_CONST_ADDR + || !(op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO)) { + efree(op_array->literals); + } } efree(op_array->opcodes); @@ -576,6 +582,8 @@ ZEND_API int pass_two(zend_op_array *op_array) op_array->vars = (zend_string**) erealloc(op_array->vars, sizeof(zend_string*)*op_array->last_var); CG(context).vars_size = op_array->last_var; } + +#if ZEND_USE_ABS_CONST_ADDR if (CG(context).opcodes_size != op_array->last) { op_array->opcodes = (zend_op *) erealloc(op_array->opcodes, sizeof(zend_op)*op_array->last); CG(context).opcodes_size = op_array->last; @@ -584,6 +592,20 @@ ZEND_API int pass_two(zend_op_array *op_array) op_array->literals = (zval*)erealloc(op_array->literals, sizeof(zval) * op_array->last_literal); CG(context).literals_size = op_array->last_literal; } +#else + op_array->opcodes = (zend_op *) erealloc(op_array->opcodes, + ZEND_MM_ALIGNED_SIZE_EX(sizeof(zend_op) * op_array->last, 16) + + sizeof(zval) * op_array->last_literal); + if (op_array->literals) { + memcpy(((char*)op_array->opcodes) + ZEND_MM_ALIGNED_SIZE_EX(sizeof(zend_op) * op_array->last, 16), + op_array->literals, sizeof(zval) * op_array->last_literal); + efree(op_array->literals); + op_array->literals = (zval*)(((char*)op_array->opcodes) + ZEND_MM_ALIGNED_SIZE_EX(sizeof(zend_op) * op_array->last, 16)); + } + CG(context).opcodes_size = op_array->last; + CG(context).literals_size = op_array->last_literal; +#endif + opline = op_array->opcodes; end = opline + op_array->last; while (opline < end) { @@ -671,12 +693,12 @@ ZEND_API int pass_two(zend_op_array *op_array) } } if (opline->op1_type == IS_CONST) { - ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op1); + ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline, opline->op1); } else if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { opline->op1.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->op1.var); } if (opline->op2_type == IS_CONST) { - ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op2); + ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline, opline->op2); } else if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) { opline->op2.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->op2.var); } diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 2054bbcee7..1b155f88f7 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -80,12 +80,12 @@ static const unsigned char tolower_map[256] = { zend_binary_strncasecmp */ -ZEND_API int ZEND_FASTCALL zend_atoi(const char *str, int str_len) /* {{{ */ +ZEND_API int ZEND_FASTCALL zend_atoi(const char *str, size_t str_len) /* {{{ */ { int retval; if (!str_len) { - str_len = (int)strlen(str); + str_len = strlen(str); } retval = ZEND_STRTOL(str, NULL, 0); if (str_len>0) { @@ -108,12 +108,12 @@ ZEND_API int ZEND_FASTCALL zend_atoi(const char *str, int str_len) /* {{{ */ } /* }}} */ -ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, int str_len) /* {{{ */ +ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len) /* {{{ */ { zend_long retval; if (!str_len) { - str_len = (int)strlen(str); + str_len = strlen(str); } retval = ZEND_STRTOL(str, NULL, 0); if (str_len>0) { @@ -508,7 +508,7 @@ ZEND_API void ZEND_FASTCALL _convert_to_cstring(zval *op ZEND_FILE_LINE_DC) /* { zend_string *str; double dval = Z_DVAL_P(op); - str = zend_strpprintf(0, "%.*H", (int) EG(precision), dval); + str = zend_strpprintf_unchecked(0, "%.*H", (int) EG(precision), dval); ZVAL_NEW_STR(op, str); } else { _convert_to_string(op ZEND_FILE_LINE_CC); @@ -583,8 +583,7 @@ static void convert_scalar_to_array(zval *op) /* {{{ */ ZVAL_COPY_VALUE(&entry, op); - ZVAL_NEW_ARR(op); - zend_hash_init(Z_ARRVAL_P(op), 8, NULL, ZVAL_PTR_DTOR, 0); + array_init_size(op, 1); zend_hash_index_add_new(Z_ARRVAL_P(op), 0, &entry); } /* }}} */ @@ -608,7 +607,7 @@ try_again: /* fast copy */ if (!Z_OBJCE_P(op)->default_properties_count && obj_ht == Z_OBJ_P(op)->properties && - !ZEND_HASH_GET_APPLY_COUNT(Z_OBJ_P(op)->properties) && + !GC_IS_RECURSIVE(obj_ht) && EXPECTED(Z_OBJ_P(op)->handlers == &std_object_handlers)) { arr = zend_proptable_to_symtable(obj_ht, 0); } else { @@ -630,12 +629,13 @@ try_again: } zval_dtor(op); + /*ZVAL_EMPTY_ARRAY(op);*/ array_init(op); } break; case IS_NULL: - ZVAL_NEW_ARR(op); - zend_hash_init(Z_ARRVAL_P(op), 8, NULL, ZVAL_PTR_DTOR, 0); + /*ZVAL_EMPTY_ARRAY(op);*/ + array_init(op); break; case IS_REFERENCE: zend_unwrap_reference(op); @@ -788,7 +788,7 @@ try_again: } /* }}} */ -ZEND_API zend_long ZEND_FASTCALL _zval_get_long_func(zval *op) /* {{{ */ +ZEND_API zend_long ZEND_FASTCALL zval_get_long_func(zval *op) /* {{{ */ { return _zval_get_long_func_ex(op, 1); } @@ -800,7 +800,7 @@ static zend_long ZEND_FASTCALL _zval_get_long_func_noisy(zval *op) /* {{{ */ } /* }}} */ -ZEND_API double ZEND_FASTCALL _zval_get_double_func(zval *op) /* {{{ */ +ZEND_API double ZEND_FASTCALL zval_get_double_func(zval *op) /* {{{ */ { try_again: switch (Z_TYPE_P(op)) { @@ -839,7 +839,7 @@ try_again: } /* }}} */ -ZEND_API zend_string* ZEND_FASTCALL _zval_get_string_func(zval *op) /* {{{ */ +ZEND_API zend_string* ZEND_FASTCALL zval_get_string_func(zval *op) /* {{{ */ { try_again: switch (Z_TYPE_P(op)) { @@ -922,7 +922,9 @@ ZEND_API int ZEND_FASTCALL add_function(zval *result, zval *op1, zval *op2) /* { return SUCCESS; } if (result != op1) { - ZVAL_DUP(result, op1); + ZVAL_ARR(result, zend_array_dup(Z_ARR_P(op1))); + } else { + SEPARATE_ARRAY(result); } zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), zval_add_ref, 0); return SUCCESS; @@ -1744,7 +1746,18 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) / } } while (0); - { + if (UNEXPECTED(Z_STRLEN_P(op1) == 0)) { + if (EXPECTED(result != op2)) { + if (result == orig_op1) { + zval_dtor(orig_op1); + } + ZVAL_COPY(result, op2); + } + } else if (UNEXPECTED(Z_STRLEN_P(op2) == 0)) { + if (EXPECTED(result != op1)) { + ZVAL_COPY(result, op1); + } + } else { size_t op1_len = Z_STRLEN_P(op1); size_t op2_len = Z_STRLEN_P(op2); size_t result_len = op1_len + op2_len; @@ -1796,8 +1809,9 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) / ZEND_API int ZEND_FASTCALL string_compare_function_ex(zval *op1, zval *op2, zend_bool case_insensitive) /* {{{ */ { - zend_string *str1 = zval_get_string(op1); - zend_string *str2 = zval_get_string(op2); + zend_string *tmp_str1, *tmp_str2; + zend_string *str1 = zval_get_tmp_string(op1, &tmp_str1); + zend_string *str2 = zval_get_tmp_string(op2, &tmp_str2); int ret; if (case_insensitive) { @@ -1806,8 +1820,8 @@ ZEND_API int ZEND_FASTCALL string_compare_function_ex(zval *op1, zval *op2, zend ret = zend_binary_strcmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2)); } - zend_string_release(str1); - zend_string_release(str2); + zend_tmp_string_release(tmp_str1); + zend_tmp_string_release(tmp_str2); return ret; } /* }}} */ @@ -1822,12 +1836,13 @@ ZEND_API int ZEND_FASTCALL string_compare_function(zval *op1, zval *op2) /* {{{ return zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2)); } } else { - zend_string *str1 = zval_get_string(op1); - zend_string *str2 = zval_get_string(op2); + zend_string *tmp_str1, *tmp_str2; + zend_string *str1 = zval_get_tmp_string(op1, &tmp_str1); + zend_string *str2 = zval_get_tmp_string(op2, &tmp_str2); int ret = zend_binary_strcmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2)); - zend_string_release(str1); - zend_string_release(str2); + zend_tmp_string_release(tmp_str1); + zend_tmp_string_release(tmp_str2); return ret; } } @@ -1843,12 +1858,13 @@ ZEND_API int ZEND_FASTCALL string_case_compare_function(zval *op1, zval *op2) /* return zend_binary_strcasecmp_l(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2)); } } else { - zend_string *str1 = zval_get_string(op1); - zend_string *str2 = zval_get_string(op2); + zend_string *tmp_str1, *tmp_str2; + zend_string *str1 = zval_get_tmp_string(op1, &tmp_str1); + zend_string *str2 = zval_get_tmp_string(op2, &tmp_str2); int ret = zend_binary_strcasecmp_l(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str1)); - zend_string_release(str1); - zend_string_release(str2); + zend_tmp_string_release(tmp_str1); + zend_tmp_string_release(tmp_str2); return ret; } } @@ -1857,12 +1873,13 @@ ZEND_API int ZEND_FASTCALL string_case_compare_function(zval *op1, zval *op2) /* #if HAVE_STRCOLL ZEND_API int ZEND_FASTCALL string_locale_compare_function(zval *op1, zval *op2) /* {{{ */ { - zend_string *str1 = zval_get_string(op1); - zend_string *str2 = zval_get_string(op2); + zend_string *tmp_str1, *tmp_str2; + zend_string *str1 = zval_get_tmp_string(op1, &tmp_str1); + zend_string *str2 = zval_get_tmp_string(op2, &tmp_str2); int ret = strcoll(ZSTR_VAL(str1), ZSTR_VAL(str2)); - zend_string_release(str1); - zend_string_release(str2); + zend_tmp_string_release(tmp_str1); + zend_tmp_string_release(tmp_str2); return ret; } /* }}} */ @@ -2126,9 +2143,7 @@ ZEND_API int ZEND_FASTCALL zend_is_identical(zval *op1, zval *op2) /* {{{ */ case IS_DOUBLE: return (Z_DVAL_P(op1) == Z_DVAL_P(op2)); case IS_STRING: - return (Z_STR_P(op1) == Z_STR_P(op2) || - (Z_STRLEN_P(op1) == Z_STRLEN_P(op2) && - memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0)); + return zend_string_equals(Z_STR_P(op1), Z_STR_P(op2)); case IS_ARRAY: return (Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2) || zend_hash_compare(Z_ARRVAL_P(op1), Z_ARRVAL_P(op2), (compare_func_t) hash_zval_identical_function, 1) == 0); @@ -2589,14 +2604,14 @@ ZEND_API char* ZEND_FASTCALL zend_str_tolower_dup_ex(const char *source, size_t } /* }}} */ -ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower(zend_string *str) /* {{{ */ +ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, int persistent) /* {{{ */ { register unsigned char *p = (unsigned char*)ZSTR_VAL(str); register unsigned char *end = p + ZSTR_LEN(str); while (p < end) { if (*p != zend_tolower_ascii(*p)) { - zend_string *res = zend_string_alloc(ZSTR_LEN(str), 0); + zend_string *res = zend_string_alloc(ZSTR_LEN(str), persistent); register unsigned char *r; if (p != (unsigned char*)ZSTR_VAL(str)) { @@ -2759,7 +2774,7 @@ ZEND_API int ZEND_FASTCALL zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval } /* }}} */ -ZEND_API zend_long ZEND_FASTCALL zendi_smart_strcmp(zend_string *s1, zend_string *s2) /* {{{ */ +ZEND_API int ZEND_FASTCALL zendi_smart_strcmp(zend_string *s1, zend_string *s2) /* {{{ */ { int ret1, ret2; int oflow1, oflow2; @@ -3032,7 +3047,7 @@ ZEND_API const char* ZEND_FASTCALL zend_memnstr_ex(const char *haystack, const c register size_t i; register const char *p; - if (needle_len == 0 || (end - haystack) == 0) { + if (needle_len == 0 || (end - haystack) < needle_len) { return NULL; } @@ -3066,7 +3081,7 @@ ZEND_API const char* ZEND_FASTCALL zend_memnrstr_ex(const char *haystack, const register size_t i; register const char *p; - if (needle_len == 0 || (end - haystack) == 0) { + if (needle_len == 0 || (end - haystack) < needle_len) { return NULL; } diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 9c2df28479..a21727f7ab 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -38,6 +38,7 @@ #include "zend_portability.h" #include "zend_strtod.h" #include "zend_multiply.h" +#include "zend_object_handlers.h" #define LONG_SIGN_MASK (((zend_long)1) << (8*sizeof(zend_long)-1)) @@ -172,7 +173,7 @@ zend_memnstr(const char *haystack, const char *needle, size_t needle_len, const while (p <= end) { if ((p = (const char *)memchr(p, *needle, (end-p+1))) && ne == p[needle_len-1]) { - if (!memcmp(needle, p, needle_len-1)) { + if (!memcmp(needle+1, p+1, needle_len-2)) { return p; } } @@ -193,7 +194,7 @@ zend_memnstr(const char *haystack, const char *needle, size_t needle_len, const static zend_always_inline const void *zend_memrchr(const void *s, int c, size_t n) { const unsigned char *e; - if (n <= 0) { + if (0 == n) { return NULL; } @@ -230,7 +231,7 @@ zend_memnrstr(const char *haystack, const char *needle, size_t needle_len, char do { if ((p = (const char *)zend_memrchr(haystack, *needle, (p - haystack) + 1)) && ne == p[needle_len-1]) { - if (!memcmp(needle, p, needle_len - 1)) { + if (!memcmp(needle + 1, p + 1, needle_len - 2)) { return p; } } @@ -259,23 +260,41 @@ ZEND_API void multi_convert_to_long_ex(int argc, ...); ZEND_API void multi_convert_to_double_ex(int argc, ...); ZEND_API void multi_convert_to_string_ex(int argc, ...); -ZEND_API zend_long ZEND_FASTCALL _zval_get_long_func(zval *op); -ZEND_API double ZEND_FASTCALL _zval_get_double_func(zval *op); -ZEND_API zend_string* ZEND_FASTCALL _zval_get_string_func(zval *op); +ZEND_API zend_long ZEND_FASTCALL zval_get_long_func(zval *op); +ZEND_API double ZEND_FASTCALL zval_get_double_func(zval *op); +ZEND_API zend_string* ZEND_FASTCALL zval_get_string_func(zval *op); -static zend_always_inline zend_long _zval_get_long(zval *op) { - return Z_TYPE_P(op) == IS_LONG ? Z_LVAL_P(op) : _zval_get_long_func(op); +static zend_always_inline zend_long zval_get_long(zval *op) { + return EXPECTED(Z_TYPE_P(op) == IS_LONG) ? Z_LVAL_P(op) : zval_get_long_func(op); } -static zend_always_inline double _zval_get_double(zval *op) { - return Z_TYPE_P(op) == IS_DOUBLE ? Z_DVAL_P(op) : _zval_get_double_func(op); +static zend_always_inline double zval_get_double(zval *op) { + return EXPECTED(Z_TYPE_P(op) == IS_DOUBLE) ? Z_DVAL_P(op) : zval_get_double_func(op); } -static zend_always_inline zend_string *_zval_get_string(zval *op) { - return Z_TYPE_P(op) == IS_STRING ? zend_string_copy(Z_STR_P(op)) : _zval_get_string_func(op); +static zend_always_inline zend_string *zval_get_string(zval *op) { + return EXPECTED(Z_TYPE_P(op) == IS_STRING) ? zend_string_copy(Z_STR_P(op)) : zval_get_string_func(op); } -#define zval_get_long(op) _zval_get_long((op)) -#define zval_get_double(op) _zval_get_double((op)) -#define zval_get_string(op) _zval_get_string((op)) +static zend_always_inline zend_string *zval_get_tmp_string(zval *op, zend_string **tmp) { + if (EXPECTED(Z_TYPE_P(op) == IS_STRING)) { + *tmp = NULL; + return Z_STR_P(op); + } else { + return *tmp = zval_get_string_func(op); + } +} +static zend_always_inline void zend_tmp_string_release(zend_string *tmp) { + if (UNEXPECTED(tmp)) { + zend_string_release(tmp); + } +} + +/* Compatibility macros for 7.2 and below */ +#define _zval_get_long(op) zval_get_long(op) +#define _zval_get_double(op) zval_get_double(op) +#define _zval_get_string(op) zval_get_string(op) +#define _zval_get_long_func(op) zval_get_long_func(op) +#define _zval_get_double_func(op) zval_get_double_func(op) +#define _zval_get_string_func(op) zval_get_string_func(op) #define convert_to_cstring(op) if (Z_TYPE_P(op) != IS_STRING) { _convert_to_cstring((op) ZEND_FILE_LINE_CC); } #define convert_to_string(op) if (Z_TYPE_P(op) != IS_STRING) { _convert_to_string((op) ZEND_FILE_LINE_CC); } @@ -317,7 +336,11 @@ again: } break; case IS_OBJECT: - result = zend_object_is_true(op); + if (EXPECTED(Z_OBJ_HT_P(op)->cast_object == zend_std_cast_object_tostring)) { + result = 1; + } else { + result = zend_object_is_true(op); + } break; case IS_RESOURCE: if (EXPECTED(Z_RES_HANDLE_P(op))) { @@ -348,7 +371,9 @@ ZEND_API void ZEND_FASTCALL zend_str_tolower(char *str, size_t length); ZEND_API char* ZEND_FASTCALL zend_str_tolower_copy(char *dest, const char *source, size_t length); ZEND_API char* ZEND_FASTCALL zend_str_tolower_dup(const char *source, size_t length); ZEND_API char* ZEND_FASTCALL zend_str_tolower_dup_ex(const char *source, size_t length); -ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower(zend_string *str); +ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, int persistent); + +#define zend_string_tolower(str) zend_string_tolower_ex(str, 0) ZEND_API int ZEND_FASTCALL zend_binary_zval_strcmp(zval *s1, zval *s2); ZEND_API int ZEND_FASTCALL zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3); @@ -361,13 +386,13 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp(const char *s1, size_t len1, ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2); ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2, size_t length); -ZEND_API zend_long ZEND_FASTCALL zendi_smart_strcmp(zend_string *s1, zend_string *s2); +ZEND_API int ZEND_FASTCALL zendi_smart_strcmp(zend_string *s1, zend_string *s2); ZEND_API int ZEND_FASTCALL zend_compare_symbol_tables(HashTable *ht1, HashTable *ht2); ZEND_API int ZEND_FASTCALL zend_compare_arrays(zval *a1, zval *a2); ZEND_API int ZEND_FASTCALL zend_compare_objects(zval *o1, zval *o2); -ZEND_API int ZEND_FASTCALL zend_atoi(const char *str, int str_len); -ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, int str_len); +ZEND_API int ZEND_FASTCALL zend_atoi(const char *str, size_t str_len); +ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len); ZEND_API void ZEND_FASTCALL zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC); @@ -441,7 +466,29 @@ ZEND_API void zend_update_current_locale(void); static zend_always_inline void fast_long_increment_function(zval *op1) { -#if PHP_HAVE_BUILTIN_SADDL_OVERFLOW && SIZEOF_LONG == SIZEOF_ZEND_LONG +#if defined(HAVE_ASM_GOTO) && defined(__i386__) + __asm__ goto( + "incl (%0)\n\t" + "jo %l1\n" + : + : "r"(&op1->value) + : "cc", "memory" + : overflow); + return; +overflow: ZEND_ATTRIBUTE_COLD_LABEL + ZVAL_DOUBLE(op1, (double)ZEND_LONG_MAX + 1.0); +#elif defined(HAVE_ASM_GOTO) && defined(__x86_64__) + __asm__ goto( + "incq (%0)\n\t" + "jo %l1\n" + : + : "r"(&op1->value) + : "cc", "memory" + : overflow); + return; +overflow: ZEND_ATTRIBUTE_COLD_LABEL + ZVAL_DOUBLE(op1, (double)ZEND_LONG_MAX + 1.0); +#elif PHP_HAVE_BUILTIN_SADDL_OVERFLOW && SIZEOF_LONG == SIZEOF_ZEND_LONG long lresult; if (UNEXPECTED(__builtin_saddl_overflow(Z_LVAL_P(op1), 1, &lresult))) { /* switch to double */ @@ -457,32 +504,6 @@ static zend_always_inline void fast_long_increment_function(zval *op1) } else { Z_LVAL_P(op1) = llresult; } -#elif defined(__GNUC__) && defined(__i386__) - __asm__( - "incl (%0)\n\t" - "jno 0f\n\t" - "movl $0x0, (%0)\n\t" - "movl $0x41e00000, 0x4(%0)\n\t" - "movl %1, %c2(%0)\n" - "0:" - : - : "r"(&op1->value), - "n"(IS_DOUBLE), - "n"(ZVAL_OFFSETOF_TYPE) - : "cc", "memory"); -#elif defined(__GNUC__) && defined(__x86_64__) - __asm__( - "incq (%0)\n\t" - "jno 0f\n\t" - "movl $0x0, (%0)\n\t" - "movl $0x43e00000, 0x4(%0)\n\t" - "movl %1, %c2(%0)\n" - "0:" - : - : "r"(&op1->value), - "n"(IS_DOUBLE), - "n"(ZVAL_OFFSETOF_TYPE) - : "cc", "memory"); #else if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MAX)) { /* switch to double */ @@ -495,7 +516,29 @@ static zend_always_inline void fast_long_increment_function(zval *op1) static zend_always_inline void fast_long_decrement_function(zval *op1) { -#if PHP_HAVE_BUILTIN_SSUBL_OVERFLOW && SIZEOF_LONG == SIZEOF_ZEND_LONG +#if defined(HAVE_ASM_GOTO) && defined(__i386__) + __asm__ goto( + "decl (%0)\n\t" + "jo %l1\n" + : + : "r"(&op1->value) + : "cc", "memory" + : overflow); + return; +overflow: ZEND_ATTRIBUTE_COLD_LABEL + ZVAL_DOUBLE(op1, (double)ZEND_LONG_MIN - 1.0); +#elif defined(HAVE_ASM_GOTO) && defined(__x86_64__) + __asm__ goto( + "decq (%0)\n\t" + "jo %l1\n" + : + : "r"(&op1->value) + : "cc", "memory" + : overflow); + return; +overflow: ZEND_ATTRIBUTE_COLD_LABEL + ZVAL_DOUBLE(op1, (double)ZEND_LONG_MIN - 1.0); +#elif PHP_HAVE_BUILTIN_SSUBL_OVERFLOW && SIZEOF_LONG == SIZEOF_ZEND_LONG long lresult; if (UNEXPECTED(__builtin_ssubl_overflow(Z_LVAL_P(op1), 1, &lresult))) { /* switch to double */ @@ -511,32 +554,6 @@ static zend_always_inline void fast_long_decrement_function(zval *op1) } else { Z_LVAL_P(op1) = llresult; } -#elif defined(__GNUC__) && defined(__i386__) - __asm__( - "decl (%0)\n\t" - "jno 0f\n\t" - "movl $0x00200000, (%0)\n\t" - "movl $0xc1e00000, 0x4(%0)\n\t" - "movl %1,%c2(%0)\n" - "0:" - : - : "r"(&op1->value), - "n"(IS_DOUBLE), - "n"(ZVAL_OFFSETOF_TYPE) - : "cc", "memory"); -#elif defined(__GNUC__) && defined(__x86_64__) - __asm__( - "decq (%0)\n\t" - "jno 0f\n\t" - "movl $0x00000000, (%0)\n\t" - "movl $0xc3e00000, 0x4(%0)\n\t" - "movl %1,%c2(%0)\n" - "0:" - : - : "r"(&op1->value), - "n"(IS_DOUBLE), - "n"(ZVAL_OFFSETOF_TYPE) - : "cc", "memory"); #else if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MIN)) { /* switch to double */ @@ -549,69 +566,56 @@ static zend_always_inline void fast_long_decrement_function(zval *op1) static zend_always_inline void fast_long_add_function(zval *result, zval *op1, zval *op2) { -#if PHP_HAVE_BUILTIN_SADDL_OVERFLOW && SIZEOF_LONG == SIZEOF_ZEND_LONG - long lresult; - if (UNEXPECTED(__builtin_saddl_overflow(Z_LVAL_P(op1), Z_LVAL_P(op2), &lresult))) { - ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2)); - } else { - ZVAL_LONG(result, lresult); - } -#elif PHP_HAVE_BUILTIN_SADDLL_OVERFLOW && SIZEOF_LONG_LONG == SIZEOF_ZEND_LONG - long long llresult; - if (UNEXPECTED(__builtin_saddll_overflow(Z_LVAL_P(op1), Z_LVAL_P(op2), &llresult))) { - ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2)); - } else { - ZVAL_LONG(result, llresult); - } -#elif defined(__GNUC__) && defined(__i386__) \ - && !(4 == __GNUC__ && 8 == __GNUC_MINOR__) \ - && !(4 == __GNUC__ && 9 == __GNUC_MINOR__ && (defined(__PIC__) || defined(__PIE__))) - /* Position-independent builds fail with gcc-4.9.x */ - __asm__( +#if defined(HAVE_ASM_GOTO) && defined(__i386__) + __asm__ goto( "movl (%1), %%eax\n\t" "addl (%2), %%eax\n\t" - "jo 0f\n\t" + "jo %l5\n\t" "movl %%eax, (%0)\n\t" - "movl %3, %c5(%0)\n\t" - "jmp 1f\n" - "0:\n\t" - "fildl (%1)\n\t" - "fildl (%2)\n\t" - "faddp %%st, %%st(1)\n\t" - "movl %4, %c5(%0)\n\t" - "fstpl (%0)\n" - "1:" + "movl %3, %c4(%0)\n" : : "r"(&result->value), "r"(&op1->value), "r"(&op2->value), "n"(IS_LONG), - "n"(IS_DOUBLE), "n"(ZVAL_OFFSETOF_TYPE) - : "eax","cc", "memory"); -#elif defined(__GNUC__) && defined(__x86_64__) - __asm__( + : "eax","cc", "memory" + : overflow); + return; +overflow: ZEND_ATTRIBUTE_COLD_LABEL + ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2)); +#elif defined(HAVE_ASM_GOTO) && defined(__x86_64__) + __asm__ goto( "movq (%1), %%rax\n\t" "addq (%2), %%rax\n\t" - "jo 0f\n\t" + "jo %l5\n\t" "movq %%rax, (%0)\n\t" - "movl %3, %c5(%0)\n\t" - "jmp 1f\n" - "0:\n\t" - "fildq (%1)\n\t" - "fildq (%2)\n\t" - "faddp %%st, %%st(1)\n\t" - "movl %4, %c5(%0)\n\t" - "fstpl (%0)\n" - "1:" + "movl %3, %c4(%0)\n" : : "r"(&result->value), "r"(&op1->value), "r"(&op2->value), "n"(IS_LONG), - "n"(IS_DOUBLE), "n"(ZVAL_OFFSETOF_TYPE) - : "rax","cc", "memory"); + : "rax","cc", "memory" + : overflow); + return; +overflow: ZEND_ATTRIBUTE_COLD_LABEL + ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2)); +#elif PHP_HAVE_BUILTIN_SADDL_OVERFLOW && SIZEOF_LONG == SIZEOF_ZEND_LONG + long lresult; + if (UNEXPECTED(__builtin_saddl_overflow(Z_LVAL_P(op1), Z_LVAL_P(op2), &lresult))) { + ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2)); + } else { + ZVAL_LONG(result, lresult); + } +#elif PHP_HAVE_BUILTIN_SADDLL_OVERFLOW && SIZEOF_LONG_LONG == SIZEOF_ZEND_LONG + long long llresult; + if (UNEXPECTED(__builtin_saddll_overflow(Z_LVAL_P(op1), Z_LVAL_P(op2), &llresult))) { + ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2)); + } else { + ZVAL_LONG(result, llresult); + } #else /* * 'result' may alias with op1 or op2, so we need to @@ -652,77 +656,56 @@ static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *o static zend_always_inline void fast_long_sub_function(zval *result, zval *op1, zval *op2) { -#if PHP_HAVE_BUILTIN_SSUBL_OVERFLOW && SIZEOF_LONG == SIZEOF_ZEND_LONG - long lresult; - if (UNEXPECTED(__builtin_ssubl_overflow(Z_LVAL_P(op1), Z_LVAL_P(op2), &lresult))) { - ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2)); - } else { - ZVAL_LONG(result, lresult); - } -#elif PHP_HAVE_BUILTIN_SSUBLL_OVERFLOW && SIZEOF_LONG_LONG == SIZEOF_ZEND_LONG - long long llresult; - if (UNEXPECTED(__builtin_ssubll_overflow(Z_LVAL_P(op1), Z_LVAL_P(op2), &llresult))) { - ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2)); - } else { - ZVAL_LONG(result, llresult); - } -#elif defined(__GNUC__) && defined(__i386__) && \ - !(4 == __GNUC__ && 8 == __GNUC_MINOR__) && \ - !(4 == __GNUC__ && 9 == __GNUC_MINOR__ && (defined(__PIC__) || defined(__PIE__))) - /* Position-independent builds fail with gcc-4.9.x */ - __asm__( +#if defined(HAVE_ASM_GOTO) && defined(__i386__) + __asm__ goto( "movl (%1), %%eax\n\t" "subl (%2), %%eax\n\t" - "jo 0f\n\t" + "jo %l5\n\t" "movl %%eax, (%0)\n\t" - "movl %3, %c5(%0)\n\t" - "jmp 1f\n" - "0:\n\t" - "fildl (%2)\n\t" - "fildl (%1)\n\t" -#if defined(__clang__) && (__clang_major__ < 2 || (__clang_major__ == 2 && __clang_minor__ < 10)) - "fsubp %%st(1), %%st\n\t" /* LLVM bug #9164 */ -#else - "fsubp %%st, %%st(1)\n\t" -#endif - "movl %4, %c5(%0)\n\t" - "fstpl (%0)\n" - "1:" + "movl %3, %c4(%0)\n" : : "r"(&result->value), "r"(&op1->value), "r"(&op2->value), "n"(IS_LONG), - "n"(IS_DOUBLE), "n"(ZVAL_OFFSETOF_TYPE) - : "eax","cc", "memory"); -#elif defined(__GNUC__) && defined(__x86_64__) - __asm__( + : "eax","cc", "memory" + : overflow); + return; +overflow: ZEND_ATTRIBUTE_COLD_LABEL + ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2)); +#elif defined(HAVE_ASM_GOTO) && defined(__x86_64__) + __asm__ goto( "movq (%1), %%rax\n\t" "subq (%2), %%rax\n\t" - "jo 0f\n\t" + "jo %l5\n\t" "movq %%rax, (%0)\n\t" - "movl %3, %c5(%0)\n\t" - "jmp 1f\n" - "0:\n\t" - "fildq (%2)\n\t" - "fildq (%1)\n\t" -#if defined(__clang__) && (__clang_major__ < 2 || (__clang_major__ == 2 && __clang_minor__ < 10)) - "fsubp %%st(1), %%st\n\t" /* LLVM bug #9164 */ -#else - "fsubp %%st, %%st(1)\n\t" -#endif - "movl %4, %c5(%0)\n\t" - "fstpl (%0)\n" - "1:" + "movl %3, %c4(%0)\n" : : "r"(&result->value), "r"(&op1->value), "r"(&op2->value), "n"(IS_LONG), - "n"(IS_DOUBLE), "n"(ZVAL_OFFSETOF_TYPE) - : "rax","cc", "memory"); + : "rax","cc", "memory" + : overflow); + return; +overflow: ZEND_ATTRIBUTE_COLD_LABEL + ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2)); +#elif PHP_HAVE_BUILTIN_SSUBL_OVERFLOW && SIZEOF_LONG == SIZEOF_ZEND_LONG + long lresult; + if (UNEXPECTED(__builtin_ssubl_overflow(Z_LVAL_P(op1), Z_LVAL_P(op2), &lresult))) { + ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2)); + } else { + ZVAL_LONG(result, lresult); + } +#elif PHP_HAVE_BUILTIN_SSUBLL_OVERFLOW && SIZEOF_LONG_LONG == SIZEOF_ZEND_LONG + long long llresult; + if (UNEXPECTED(__builtin_ssubll_overflow(Z_LVAL_P(op1), Z_LVAL_P(op2), &llresult))) { + ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2)); + } else { + ZVAL_LONG(result, llresult); + } #else ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); @@ -738,6 +721,17 @@ static zend_always_inline int fast_div_function(zval *result, zval *op1, zval *o return div_function(result, op1, op2); } +static zend_always_inline int zend_fast_equal_strings(zend_string *s1, zend_string *s2) +{ + if (s1 == s2) { + return 1; + } else if (ZSTR_VAL(s1)[0] > '9' || ZSTR_VAL(s2)[0] > '9') { + return zend_string_equal_content(s1, s2); + } else { + return zendi_smart_strcmp(s1, s2) == 0; + } +} + static zend_always_inline int fast_equal_check_function(zval *op1, zval *op2) { zval result; @@ -755,17 +749,7 @@ static zend_always_inline int fast_equal_check_function(zval *op1, zval *op2) } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - return 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - return 0; - } else { - return memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0; - } - } else { - return zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0; - } + return zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); } } compare_function(&result, op1, op2); @@ -786,17 +770,7 @@ static zend_always_inline int fast_equal_check_string(zval *op1, zval *op2) { zval result; if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - return 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - return 0; - } else { - return memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0; - } - } else { - return zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0; - } + return zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); } compare_function(&result, op1, op2); return Z_LVAL(result) == 0; diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index ec140b3f54..0573550719 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -197,17 +197,13 @@ char *alloca(); # define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y) #endif -/* Format string checks are disabled by default, because we use custom format modifiers (like %p), - * which cause a large amount of false positives. You can enable format checks by adding - * -DZEND_CHECK_FORMAT_STRINGS to CFLAGS. */ - -#if defined(ZEND_CHECK_FORMAT_STRINGS) && (ZEND_GCC_VERSION >= 2007 || __has_attribute(format)) +#if ZEND_GCC_VERSION >= 2007 || __has_attribute(format) # define ZEND_ATTRIBUTE_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first))) #else # define ZEND_ATTRIBUTE_FORMAT(type, idx, first) #endif -#if defined(ZEND_CHECK_FORMAT_STRINGS) && ((ZEND_GCC_VERSION >= 3001 && !defined(__INTEL_COMPILER)) || __has_attribute(format)) +#if (ZEND_GCC_VERSION >= 3001 && !defined(__INTEL_COMPILER)) || __has_attribute(format) # define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first))) #else # define ZEND_ATTRIBUTE_PTR_FORMAT(type, idx, first) @@ -223,16 +219,24 @@ char *alloca(); #if defined(__GNUC__) && ZEND_GCC_VERSION >= 4003 # define ZEND_ATTRIBUTE_UNUSED __attribute__((unused)) -# define ZEND_ATTRIBUTE_UNUSED_LABEL __attribute__((cold, unused)); # define ZEND_COLD __attribute__((cold)) # define ZEND_HOT __attribute__((hot)) #else # define ZEND_ATTRIBUTE_UNUSED -# define ZEND_ATTRIBUTE_UNUSED_LABEL # define ZEND_COLD # define ZEND_HOT #endif +#if defined(__GNUC__) && ZEND_GCC_VERSION >= 5000 +# define ZEND_ATTRIBUTE_UNUSED_LABEL __attribute__((cold, unused)); +# define ZEND_ATTRIBUTE_COLD_LABEL __attribute__((cold)); +# define ZEND_ATTRIBUTE_HOT_LABEL __attribute__((hot)); +#else +# define ZEND_ATTRIBUTE_UNUSED_LABEL +# define ZEND_ATTRIBUTE_COLD_LABEL +# define ZEND_ATTRIBUTE_HOT_LABEL +#endif + #if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__) # define ZEND_FASTCALL __attribute__((fastcall)) #elif defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER == 1700 diff --git a/Zend/zend_smart_str.c b/Zend/zend_smart_str.c index b020fddbaa..cf7c40b283 100644 --- a/Zend/zend_smart_str.c +++ b/Zend/zend_smart_str.c @@ -18,45 +18,41 @@ #include <zend.h> #include "zend_smart_str.h" +#include "zend_smart_string.h" -#define SMART_STR_OVERHEAD (ZEND_MM_OVERHEAD + _ZSTR_HEADER_SIZE) +#define SMART_STR_OVERHEAD (ZEND_MM_OVERHEAD + _ZSTR_HEADER_SIZE + 1) +#define SMART_STR_START_SIZE 256 +#define SMART_STR_START_LEN (SMART_STR_START_SIZE - SMART_STR_OVERHEAD) +#define SMART_STR_PAGE 4096 -#ifndef SMART_STR_PAGE -# define SMART_STR_PAGE 4096 -#endif - -#ifndef SMART_STR_START_SIZE -# define SMART_STR_START_SIZE (256 - SMART_STR_OVERHEAD - 1) -#endif - -#define SMART_STR_NEW_SIZE(len) \ - (((len + SMART_STR_OVERHEAD + SMART_STR_PAGE) & ~(SMART_STR_PAGE - 1)) - SMART_STR_OVERHEAD - 1) +#define SMART_STR_NEW_LEN(len) \ + (ZEND_MM_ALIGNED_SIZE_EX(len + SMART_STR_OVERHEAD, SMART_STR_PAGE) - SMART_STR_OVERHEAD) ZEND_API void ZEND_FASTCALL smart_str_erealloc(smart_str *str, size_t len) { if (UNEXPECTED(!str->s)) { - str->a = len < SMART_STR_START_SIZE - ? SMART_STR_START_SIZE - : SMART_STR_NEW_SIZE(len); + str->a = len <= SMART_STR_START_LEN + ? SMART_STR_START_LEN + : SMART_STR_NEW_LEN(len); str->s = zend_string_alloc(str->a, 0); ZSTR_LEN(str->s) = 0; } else { - str->a = SMART_STR_NEW_SIZE(len); - str->s = (zend_string *) erealloc2(str->s, _ZSTR_HEADER_SIZE + str->a + 1, _ZSTR_HEADER_SIZE + ZSTR_LEN(str->s) + 1); + str->a = SMART_STR_NEW_LEN(len); + str->s = (zend_string *) erealloc2(str->s, str->a + _ZSTR_HEADER_SIZE + 1, _ZSTR_HEADER_SIZE + ZSTR_LEN(str->s)); } } ZEND_API void ZEND_FASTCALL smart_str_realloc(smart_str *str, size_t len) { if (UNEXPECTED(!str->s)) { - str->a = len < SMART_STR_START_SIZE - ? SMART_STR_START_SIZE - : SMART_STR_NEW_SIZE(len); + str->a = len <= SMART_STR_START_SIZE + ? SMART_STR_START_LEN + : SMART_STR_NEW_LEN(len); str->s = zend_string_alloc(str->a, 1); ZSTR_LEN(str->s) = 0; } else { - str->a = SMART_STR_NEW_SIZE(len); - str->s = (zend_string *) realloc(str->s, _ZSTR_HEADER_SIZE + str->a + 1); + str->a = SMART_STR_NEW_LEN(len); + str->s = (zend_string *) perealloc(str->s, str->a + _ZSTR_HEADER_SIZE + 1, 1); } } @@ -125,6 +121,52 @@ ZEND_API void ZEND_FASTCALL smart_str_append_printf(smart_str *dest, const char va_end(arg); } +#define SMART_STRING_OVERHEAD (ZEND_MM_OVERHEAD + 1) +#define SMART_STRING_START_SIZE 256 +#define SMART_STRING_START_LEN (SMART_STRING_START_SIZE - SMART_STRING_OVERHEAD) +#define SMART_STRING_PAGE 4096 + +ZEND_API void ZEND_FASTCALL _smart_string_alloc_persistent(smart_string *str, size_t len) +{ + if (!str->c) { + str->len = 0; + if (len <= SMART_STRING_START_LEN) { + str->a = SMART_STRING_START_LEN; + } else { + str->a = ZEND_MM_ALIGNED_SIZE_EX(len + SMART_STRING_OVERHEAD, SMART_STRING_PAGE) - SMART_STRING_OVERHEAD; + } + str->c = pemalloc(str->a + 1, 1); + } else { + if (UNEXPECTED((size_t) len > SIZE_MAX - str->len)) { + zend_error(E_ERROR, "String size overflow"); + } + len += str->len; + str->a = ZEND_MM_ALIGNED_SIZE_EX(len + SMART_STRING_OVERHEAD, SMART_STRING_PAGE) - SMART_STRING_OVERHEAD; + str->c = perealloc(str->c, str->a + 1, 1); + } +} + +ZEND_API void ZEND_FASTCALL _smart_string_alloc(smart_string *str, size_t len) +{ + if (!str->c) { + str->len = 0; + if (len <= SMART_STRING_START_LEN) { + str->a = SMART_STRING_START_LEN; + str->c = emalloc(SMART_STRING_START_LEN + 1); + } else { + str->a = ZEND_MM_ALIGNED_SIZE_EX(len + SMART_STRING_OVERHEAD, SMART_STRING_PAGE) - SMART_STRING_OVERHEAD; + str->c = emalloc_large(str->a + 1); + } + } else { + if (UNEXPECTED((size_t) len > SIZE_MAX - str->len)) { + zend_error(E_ERROR, "String size overflow"); + } + len += str->len; + str->a = ZEND_MM_ALIGNED_SIZE_EX(len + SMART_STRING_OVERHEAD, SMART_STRING_PAGE) - SMART_STRING_OVERHEAD; + str->c = erealloc2(str->c, str->a + 1, str->len); + } +} + /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_smart_string.h b/Zend/zend_smart_string.h index 2282202792..464e58e520 100644 --- a/Zend/zend_smart_string.h +++ b/Zend/zend_smart_string.h @@ -25,26 +25,7 @@ #include "zend_smart_string_public.h" #include <stdlib.h> -#ifndef SMART_STR_USE_REALLOC #include <zend.h> -#endif - -#ifndef SMART_STRING_PREALLOC -#define SMART_STRING_PREALLOC 128 -#endif - -#ifndef SMART_STRING_START_SIZE -#define SMART_STRING_START_SIZE 78 -#endif - -#ifdef SMART_STRING_USE_REALLOC -#define SMART_STRING_REALLOC(a,b,c) realloc((a),(b)) -#else -#define SMART_STRING_REALLOC(a,b,c) perealloc((a),(b),(c)) -#endif - -#define SMART_STRING_DO_REALLOC(d, what) \ - (d)->c = (char *) SMART_STRING_REALLOC((d)->c, (d)->a + 1, (what)) /* wrapper */ @@ -71,25 +52,18 @@ #define smart_string_append_unsigned(str, val) \ smart_string_append_unsigned_ex((str), (val), 0) +ZEND_API void ZEND_FASTCALL _smart_string_alloc_persistent(smart_string *str, size_t len); +ZEND_API void ZEND_FASTCALL _smart_string_alloc(smart_string *str, size_t len); + static zend_always_inline size_t smart_string_alloc(smart_string *str, size_t len, zend_bool persistent) { - if (!str->c) { - str->len = 0; - str->a = len < SMART_STRING_START_SIZE - ? SMART_STRING_START_SIZE - : len + SMART_STRING_PREALLOC; - SMART_STRING_DO_REALLOC(str, persistent); - return len; - } else { - if (UNEXPECTED((size_t) len > SIZE_MAX - str->len)) { - zend_error(E_ERROR, "String size overflow"); - } - len += str->len; - if (UNEXPECTED(len >= str->a)) { - str->a = len + SMART_STRING_PREALLOC; - SMART_STRING_DO_REALLOC(str, persistent); + if (UNEXPECTED(!str->c) || UNEXPECTED(len >= str->a - str->len)) { + if (persistent) { + _smart_string_alloc_persistent(str, len); + } else { + _smart_string_alloc(str, len); } } - return len; + return str->len + len; } static zend_always_inline void smart_string_free_ex(smart_string *str, zend_bool persistent) { @@ -136,6 +110,10 @@ static zend_always_inline void smart_string_setl(smart_string *dest, char *src, dest->c = src; } +static zend_always_inline void smart_string_reset(smart_string *str) { + str->len = 0; +} + #endif /* diff --git a/Zend/zend_string.c b/Zend/zend_string.c index 4cfd3dedec..5d82cab3b2 100644 --- a/Zend/zend_string.c +++ b/Zend/zend_string.c @@ -21,19 +21,28 @@ #include "zend.h" #include "zend_globals.h" +#ifdef HAVE_VALGRIND +# include "valgrind/callgrind.h" +#endif + ZEND_API zend_string *(*zend_new_interned_string)(zend_string *str); +ZEND_API zend_string *(*zend_string_init_interned)(const char *str, size_t size, int permanent); static zend_string *zend_new_interned_string_permanent(zend_string *str); static zend_string *zend_new_interned_string_request(zend_string *str); +static zend_string *zend_string_init_interned_permanent(const char *str, size_t size, int permanent); +static zend_string *zend_string_init_interned_request(const char *str, size_t size, int permanent); /* Any strings interned in the startup phase. Common to all the threads, - won't be free'd until process exit. If we want an ability to + won't be free'd until process exit. If we want an ability to add permanent strings even after startup, it would be still possible on costs of locking in the thread safe builds. */ static HashTable interned_strings_permanent; static zend_new_interned_string_func_t interned_string_request_handler = zend_new_interned_string_request; +static zend_string_init_interned_func_t interned_string_init_request_handler = zend_string_init_interned_request; static zend_string_copy_storage_func_t interned_string_copy_storage = NULL; +static zend_string_copy_storage_func_t interned_string_restore_storage = NULL; ZEND_API zend_string *zend_empty_string = NULL; ZEND_API zend_string *zend_one_char_string[256]; @@ -72,6 +81,7 @@ ZEND_API void zend_interned_strings_init(void) zend_init_interned_strings_ht(&interned_strings_permanent, 1); zend_new_interned_string = zend_new_interned_string_permanent; + zend_string_init_interned = zend_string_init_interned_permanent; /* interned empty string */ str = zend_string_alloc(sizeof("")-1, 1); @@ -100,20 +110,18 @@ ZEND_API void zend_interned_strings_dtor(void) zend_known_strings = NULL; } -static zend_always_inline zend_string *zend_interned_string_ht_lookup(zend_string *str, HashTable *interned_strings) +static zend_always_inline zend_string *zend_interned_string_ht_lookup_ex(zend_ulong h, const char *str, size_t size, HashTable *interned_strings) { - zend_ulong h; uint32_t nIndex; uint32_t idx; Bucket *p; - h = zend_string_hash_val(str); nIndex = h | interned_strings->nTableMask; idx = HT_HASH(interned_strings, nIndex); while (idx != HT_INVALID_IDX) { p = HT_HASH_TO_BUCKET(interned_strings, idx); - if ((p->h == h) && (ZSTR_LEN(p->key) == ZSTR_LEN(str))) { - if (!memcmp(ZSTR_VAL(p->key), ZSTR_VAL(str), ZSTR_LEN(str))) { + if ((p->h == h) && (ZSTR_LEN(p->key) == size)) { + if (!memcmp(ZSTR_VAL(p->key), str, size)) { return p->key; } } @@ -123,13 +131,33 @@ static zend_always_inline zend_string *zend_interned_string_ht_lookup(zend_strin return NULL; } +static zend_always_inline zend_string *zend_interned_string_ht_lookup(zend_string *str, HashTable *interned_strings) +{ + zend_ulong h = ZSTR_H(str); + uint32_t nIndex; + uint32_t idx; + Bucket *p; + + nIndex = h | interned_strings->nTableMask; + idx = HT_HASH(interned_strings, nIndex); + while (idx != HT_INVALID_IDX) { + p = HT_HASH_TO_BUCKET(interned_strings, idx); + if ((p->h == h) && zend_string_equal_content(p->key, str)) { + return p->key; + } + idx = Z_NEXT(p->val); + } + + return NULL; +} + /* This function might be not thread safe at least because it would update the hash val in the passed string. Be sure it is called in the appropriate context. */ static zend_always_inline zend_string *zend_add_interned_string(zend_string *str, HashTable *interned_strings, uint32_t flags) { zval val; - GC_REFCOUNT(str) = 1; + GC_SET_REFCOUNT(str, 1); GC_FLAGS(str) |= IS_STR_INTERNED | flags; ZVAL_INTERNED_STR(&val, str); @@ -141,10 +169,10 @@ static zend_always_inline zend_string *zend_add_interned_string(zend_string *str ZEND_API zend_string *zend_interned_string_find_permanent(zend_string *str) { + zend_string_hash_val(str); return zend_interned_string_ht_lookup(str, &interned_strings_permanent); } - static zend_string *zend_new_interned_string_permanent(zend_string *str) { zend_string *ret; @@ -153,12 +181,21 @@ static zend_string *zend_new_interned_string_permanent(zend_string *str) return str; } + zend_string_hash_val(str); ret = zend_interned_string_ht_lookup(str, &interned_strings_permanent); if (ret) { zend_string_release(str); return ret; } + ZEND_ASSERT(GC_FLAGS(str) & GC_PERSISTENT); + if (GC_REFCOUNT(str) > 1) { + zend_ulong h = ZSTR_H(str); + zend_string_delref(str); + str = zend_string_init(ZSTR_VAL(str), ZSTR_LEN(str), 1); + ZSTR_H(str) = h; + } + return zend_add_interned_string(str, &interned_strings_permanent, IS_STR_PERMANENT); } @@ -170,6 +207,8 @@ static zend_string *zend_new_interned_string_request(zend_string *str) return str; } + zend_string_hash_val(str); + /* Check for permanent strings, the table is readonly at this point. */ ret = zend_interned_string_ht_lookup(str, &interned_strings_permanent); if (ret) { @@ -184,11 +223,57 @@ static zend_string *zend_new_interned_string_request(zend_string *str) } /* Create a short living interned, freed after the request. */ + ZEND_ASSERT(!(GC_FLAGS(str) & GC_PERSISTENT)); + if (GC_REFCOUNT(str) > 1) { + zend_ulong h = ZSTR_H(str); + zend_string_delref(str); + str = zend_string_init(ZSTR_VAL(str), ZSTR_LEN(str), 0); + ZSTR_H(str) = h; + } + ret = zend_add_interned_string(str, &CG(interned_strings), 0); return ret; } +static zend_string *zend_string_init_interned_permanent(const char *str, size_t size, int permanent) +{ + zend_string *ret; + zend_ulong h = zend_inline_hash_func(str, size); + + ret = zend_interned_string_ht_lookup_ex(h, str, size, &interned_strings_permanent); + if (ret) { + return ret; + } + + ret = zend_string_init(str, size, permanent); + ZSTR_H(ret) = h; + return zend_add_interned_string(ret, &interned_strings_permanent, IS_STR_PERMANENT); +} + +static zend_string *zend_string_init_interned_request(const char *str, size_t size, int permanent) +{ + zend_string *ret; + zend_ulong h = zend_inline_hash_func(str, size); + + /* Check for permanent strings, the table is readonly at this point. */ + ret = zend_interned_string_ht_lookup_ex(h, str, size, &interned_strings_permanent); + if (ret) { + return ret; + } + + ret = zend_interned_string_ht_lookup_ex(h, str, size, &CG(interned_strings)); + if (ret) { + return ret; + } + + ret = zend_string_init(str, size, permanent); + ZSTR_H(ret) = h; + + /* Create a short living interned, freed after the request. */ + return zend_add_interned_string(ret, &CG(interned_strings), 0); +} + ZEND_API void zend_interned_strings_activate(void) { zend_init_interned_strings_ht(&CG(interned_strings), 0); @@ -199,24 +284,173 @@ ZEND_API void zend_interned_strings_deactivate(void) zend_hash_destroy(&CG(interned_strings)); } -ZEND_API void zend_interned_strings_set_request_storage_handler(zend_new_interned_string_func_t handler) +ZEND_API void zend_interned_strings_set_request_storage_handlers(zend_new_interned_string_func_t handler, zend_string_init_interned_func_t init_handler) { interned_string_request_handler = handler; + interned_string_init_request_handler = init_handler; } -ZEND_API void zend_interned_strings_set_permanent_storage_copy_handler(zend_string_copy_storage_func_t handler) +ZEND_API void zend_interned_strings_set_permanent_storage_copy_handlers(zend_string_copy_storage_func_t copy_handler, zend_string_copy_storage_func_t restore_handler) { - interned_string_copy_storage = handler; + interned_string_copy_storage = copy_handler; + interned_string_restore_storage = restore_handler; } -ZEND_API void zend_interned_strings_switch_storage(void) +ZEND_API void zend_interned_strings_switch_storage(zend_bool request) { - if (interned_string_copy_storage) { - interned_string_copy_storage(); + if (request) { + if (interned_string_copy_storage) { + interned_string_copy_storage(); + } + zend_new_interned_string = interned_string_request_handler; + zend_string_init_interned = interned_string_init_request_handler; + } else { + zend_new_interned_string = zend_new_interned_string_permanent; + zend_string_init_interned = zend_string_init_interned_permanent; + if (interned_string_restore_storage) { + interned_string_restore_storage(); + } } - zend_new_interned_string = interned_string_request_handler; } +#if defined(__GNUC__) && defined(__i386__) +ZEND_API zend_bool ZEND_FASTCALL zend_string_equal_val(zend_string *s1, zend_string *s2) +{ + char *ptr = ZSTR_VAL(s1); + size_t delta = (char*)s2 - (char*)s1; + size_t len = ZSTR_LEN(s1); + zend_ulong ret; + + __asm__ ( + ".LL0%=:\n\t" + "movl (%2,%3), %0\n\t" + "xorl (%2), %0\n\t" + "jne .LL1%=\n\t" + "addl $0x4, %2\n\t" + "subl $0x4, %1\n\t" + "ja .LL0%=\n\t" + "movl $0x1, %0\n\t" + "jmp .LL3%=\n\t" + ".LL1%=:\n\t" + "cmpl $0x4,%1\n\t" + "jb .LL2%=\n\t" + "xorl %0, %0\n\t" + "jmp .LL3%=\n\t" + ".LL2%=:\n\t" + "negl %1\n\t" + "lea 0x1c(,%1,8), %1\n\t" + "shll %b1, %0\n\t" + "sete %b0\n\t" + "movzbl %b0, %0\n\t" + ".LL3%=:\n" + : "=&a"(ret), + "+c"(len), + "+r"(ptr) + : "r"(delta) + : "cc"); + return ret; +} + +#ifdef HAVE_VALGRIND +ZEND_API zend_bool ZEND_FASTCALL I_WRAP_SONAME_FNNAME_ZU(NONE,zend_string_equal_val)(zend_string *s1, zend_string *s2) +{ + size_t len = ZSTR_LEN(s1); + char *ptr1 = ZSTR_VAL(s1); + char *ptr2 = ZSTR_VAL(s2); + zend_ulong ret; + + __asm__ ( + "test %1, %1\n\t" + "jnz .LL1%=\n\t" + "movl $0x1, %0\n\t" + "jmp .LL2%=\n\t" + ".LL1%=:\n\t" + "cld\n\t" + "rep\n\t" + "cmpsb\n\t" + "sete %b0\n\t" + "movzbl %b0, %0\n\t" + ".LL2%=:\n" + : "=a"(ret), + "+c"(len), + "+D"(ptr1), + "+S"(ptr2) + : + : "cc"); + return ret; +} +#endif + +#elif defined(__GNUC__) && defined(__x86_64__) +ZEND_API zend_bool ZEND_FASTCALL zend_string_equal_val(zend_string *s1, zend_string *s2) +{ + char *ptr = ZSTR_VAL(s1); + size_t delta = (char*)s2 - (char*)s1; + size_t len = ZSTR_LEN(s1); + zend_ulong ret; + + __asm__ ( + ".LL0%=:\n\t" + "movq (%2,%3), %0\n\t" + "xorq (%2), %0\n\t" + "jne .LL1%=\n\t" + "addq $0x8, %2\n\t" + "subq $0x8, %1\n\t" + "ja .LL0%=\n\t" + "movq $0x1, %0\n\t" + "jmp .LL3%=\n\t" + ".LL1%=:\n\t" + "cmpq $0x8,%1\n\t" + "jb .LL2%=\n\t" + "xorq %0, %0\n\t" + "jmp .LL3%=\n\t" + ".LL2%=:\n\t" + "negq %1\n\t" + "lea 0x3c(,%1,8), %1\n\t" + "shlq %b1, %0\n\t" + "sete %b0\n\t" + "movzbq %b0, %0\n\t" + ".LL3%=:\n" + : "=&a"(ret), + "+c"(len), + "+r"(ptr) + : "r"(delta) + : "cc"); + return ret; +} + +#ifdef HAVE_VALGRIND +ZEND_API zend_bool ZEND_FASTCALL I_WRAP_SONAME_FNNAME_ZU(NONE,zend_string_equal_val)(zend_string *s1, zend_string *s2) +{ + size_t len = ZSTR_LEN(s1); + char *ptr1 = ZSTR_VAL(s1); + char *ptr2 = ZSTR_VAL(s2); + zend_ulong ret; + + __asm__ ( + "test %1, %1\n\t" + "jnz .LL1%=\n\t" + "movq $0x1, %0\n\t" + "jmp .LL2%=\n\t" + ".LL1%=:\n\t" + "cld\n\t" + "rep\n\t" + "cmpsb\n\t" + "sete %b0\n\t" + "movzbq %b0, %0\n\t" + ".LL2%=:\n" + : "=a"(ret), + "+c"(len), + "+D"(ptr1), + "+S"(ptr2) + : + : "cc"); + return ret; +} +#endif + +#endif + /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_string.h b/Zend/zend_string.h index 400795a9b2..2bbcdb80a8 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -27,8 +27,10 @@ BEGIN_EXTERN_C() typedef void (*zend_string_copy_storage_func_t)(void); typedef zend_string *(*zend_new_interned_string_func_t)(zend_string *str); +typedef zend_string *(*zend_string_init_interned_func_t)(const char *str, size_t size, int permanent); ZEND_API extern zend_new_interned_string_func_t zend_new_interned_string; +ZEND_API extern zend_string_init_interned_func_t zend_string_init_interned; ZEND_API zend_ulong zend_hash_func(const char *str, size_t len); ZEND_API void zend_interned_strings_init(void); @@ -36,9 +38,9 @@ ZEND_API void zend_interned_strings_dtor(void); ZEND_API void zend_interned_strings_activate(void); ZEND_API void zend_interned_strings_deactivate(void); ZEND_API zend_string *zend_interned_string_find_permanent(zend_string *str); -ZEND_API void zend_interned_strings_set_request_storage_handler(zend_new_interned_string_func_t handler); -ZEND_API void zend_interned_strings_set_permanent_storage_copy_handler(zend_string_copy_storage_func_t handler); -ZEND_API void zend_interned_strings_switch_storage(void); +ZEND_API void zend_interned_strings_set_request_storage_handlers(zend_new_interned_string_func_t handler, zend_string_init_interned_func_t init_handler); +ZEND_API void zend_interned_strings_set_permanent_storage_copy_handlers(zend_string_copy_storage_func_t copy_handler, zend_string_copy_storage_func_t restore_handler); +ZEND_API void zend_interned_strings_switch_storage(zend_bool request); ZEND_API extern zend_string *zend_empty_string; ZEND_API extern zend_string *zend_one_char_string[256]; @@ -76,7 +78,7 @@ END_EXTERN_C() #define ZSTR_ALLOCA_ALLOC(str, _len, use_heap) do { \ (str) = (zend_string *)do_alloca(ZEND_MM_ALIGNED_SIZE_EX(_ZSTR_STRUCT_SIZE(_len), 8), (use_heap)); \ - GC_REFCOUNT(str) = 1; \ + GC_SET_REFCOUNT(str, 1); \ GC_TYPE_INFO(str) = IS_STRING; \ zend_string_forget_hash_val(str); \ ZSTR_LEN(str) = _len; \ @@ -116,7 +118,7 @@ static zend_always_inline uint32_t zend_string_refcount(const zend_string *s) static zend_always_inline uint32_t zend_string_addref(zend_string *s) { if (!ZSTR_IS_INTERNED(s)) { - return ++GC_REFCOUNT(s); + return GC_ADDREF(s); } return 1; } @@ -124,7 +126,7 @@ static zend_always_inline uint32_t zend_string_addref(zend_string *s) static zend_always_inline uint32_t zend_string_delref(zend_string *s) { if (!ZSTR_IS_INTERNED(s)) { - return --GC_REFCOUNT(s); + return GC_DELREF(s); } return 1; } @@ -133,7 +135,7 @@ static zend_always_inline zend_string *zend_string_alloc(size_t len, int persist { zend_string *ret = (zend_string *)pemalloc(ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(len)), persistent); - GC_REFCOUNT(ret) = 1; + GC_SET_REFCOUNT(ret, 1); #if 1 /* optimized single assignment */ GC_TYPE_INFO(ret) = IS_STRING | ((persistent ? IS_STR_PERSISTENT : 0) << 8); @@ -151,7 +153,7 @@ static zend_always_inline zend_string *zend_string_safe_alloc(size_t n, size_t m { zend_string *ret = (zend_string *)safe_pemalloc(n, m, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(l)), persistent); - GC_REFCOUNT(ret) = 1; + GC_SET_REFCOUNT(ret, 1); #if 1 /* optimized single assignment */ GC_TYPE_INFO(ret) = IS_STRING | ((persistent ? IS_STR_PERSISTENT : 0) << 8); @@ -174,17 +176,10 @@ static zend_always_inline zend_string *zend_string_init(const char *str, size_t return ret; } -static zend_always_inline zend_string *zend_string_init_interned(const char *str, size_t len, int persistent) -{ - zend_string *ret = zend_string_init(str, len, persistent); - - return zend_new_interned_string(ret); -} - static zend_always_inline zend_string *zend_string_copy(zend_string *s) { if (!ZSTR_IS_INTERNED(s)) { - GC_REFCOUNT(s)++; + GC_ADDREF(s); } return s; } @@ -209,7 +204,7 @@ static zend_always_inline zend_string *zend_string_realloc(zend_string *s, size_ zend_string_forget_hash_val(ret); return ret; } else { - GC_REFCOUNT(s)--; + GC_DELREF(s); } } ret = zend_string_alloc(len, persistent); @@ -229,7 +224,7 @@ static zend_always_inline zend_string *zend_string_extend(zend_string *s, size_t zend_string_forget_hash_val(ret); return ret; } else { - GC_REFCOUNT(s)--; + GC_DELREF(s); } } ret = zend_string_alloc(len, persistent); @@ -249,7 +244,7 @@ static zend_always_inline zend_string *zend_string_truncate(zend_string *s, size zend_string_forget_hash_val(ret); return ret; } else { - GC_REFCOUNT(s)--; + GC_DELREF(s); } } ret = zend_string_alloc(len, persistent); @@ -268,7 +263,7 @@ static zend_always_inline zend_string *zend_string_safe_realloc(zend_string *s, zend_string_forget_hash_val(ret); return ret; } else { - GC_REFCOUNT(s)--; + GC_DELREF(s); } } ret = zend_string_safe_alloc(n, m, l, persistent); @@ -287,16 +282,29 @@ static zend_always_inline void zend_string_free(zend_string *s) static zend_always_inline void zend_string_release(zend_string *s) { if (!ZSTR_IS_INTERNED(s)) { - if (--GC_REFCOUNT(s) == 0) { + if (GC_DELREF(s) == 0) { pefree(s, GC_FLAGS(s) & IS_STR_PERSISTENT); } } } +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +ZEND_API zend_bool ZEND_FASTCALL zend_string_equal_val(zend_string *s1, zend_string *s2); +#else +static zend_always_inline zend_bool zend_string_equal_val(zend_string *s1, zend_string *s2) +{ + return !memcmp(ZSTR_VAL(s1), ZSTR_VAL(s2), ZSTR_LEN(s1)); +} +#endif + +static zend_always_inline zend_bool zend_string_equal_content(zend_string *s1, zend_string *s2) +{ + return ZSTR_LEN(s1) == ZSTR_LEN(s2) && zend_string_equal_val(s1, s2); +} static zend_always_inline zend_bool zend_string_equals(zend_string *s1, zend_string *s2) { - return s1 == s2 || (ZSTR_LEN(s1) == ZSTR_LEN(s2) && !memcmp(ZSTR_VAL(s1), ZSTR_VAL(s2), ZSTR_LEN(s1))); + return s1 == s2 || zend_string_equal_content(s1, s2); } #define zend_string_equals_ci(s1, s2) \ @@ -423,6 +431,9 @@ EMPTY_SWITCH_DEFAULT_CASE() _(ZEND_STR_ARRAY, "array") \ _(ZEND_STR_RESOURCE, "resource") \ _(ZEND_STR_CLOSED_RESOURCE, "resource (closed)") \ + _(ZEND_STR_NAME, "name") \ + _(ZEND_STR_ARGV, "argv") \ + _(ZEND_STR_ARGC, "argc") \ typedef enum _zend_known_string_id { diff --git a/Zend/zend_ts_hash.c b/Zend/zend_ts_hash.c index fab54672fc..931236936d 100644 --- a/Zend/zend_ts_hash.c +++ b/Zend/zend_ts_hash.c @@ -59,24 +59,14 @@ static void end_write(TsHashTable *ht) } /* delegates */ -ZEND_API void _zend_ts_hash_init(TsHashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC) +ZEND_API void _zend_ts_hash_init(TsHashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent) { #ifdef ZTS ht->mx_reader = tsrm_mutex_alloc(); ht->mx_writer = tsrm_mutex_alloc(); ht->reader = 0; #endif - _zend_hash_init(TS_HASH(ht), nSize, pDestructor, persistent ZEND_FILE_LINE_RELAY_CC); -} - -ZEND_API void _zend_ts_hash_init_ex(TsHashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC) -{ -#ifdef ZTS - ht->mx_reader = tsrm_mutex_alloc(); - ht->mx_writer = tsrm_mutex_alloc(); - ht->reader = 0; -#endif - _zend_hash_init_ex(TS_HASH(ht), nSize, pDestructor, persistent, bApplyProtection ZEND_FILE_LINE_RELAY_CC); + _zend_hash_init(TS_HASH(ht), nSize, pDestructor, persistent); } ZEND_API void zend_ts_hash_destroy(TsHashTable *ht) diff --git a/Zend/zend_ts_hash.h b/Zend/zend_ts_hash.h index 18421e58f6..20e66d3890 100644 --- a/Zend/zend_ts_hash.h +++ b/Zend/zend_ts_hash.h @@ -37,15 +37,14 @@ BEGIN_EXTERN_C() #define TS_HASH(table) (&(table->hash)) /* startup/shutdown */ -ZEND_API void _zend_ts_hash_init(TsHashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC); -ZEND_API void _zend_ts_hash_init_ex(TsHashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC); +ZEND_API void _zend_ts_hash_init(TsHashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent); ZEND_API void zend_ts_hash_destroy(TsHashTable *ht); ZEND_API void zend_ts_hash_clean(TsHashTable *ht); #define zend_ts_hash_init(ht, nSize, pHashFunction, pDestructor, persistent) \ - _zend_ts_hash_init(ht, nSize, pDestructor, persistent ZEND_FILE_LINE_CC) + _zend_ts_hash_init(ht, nSize, pDestructor, persistent) #define zend_ts_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection) \ - _zend_ts_hash_init_ex(ht, nSize, pDestructor, persistent, bApplyProtection ZEND_FILE_LINE_CC) + _zend_ts_hash_init(ht, nSize, pDestructor, persistent) /* additions/updates/changes */ diff --git a/Zend/zend_types.h b/Zend/zend_types.h index b78ed0c45a..6e7a1f3eee 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -180,11 +180,13 @@ struct _zval_struct { zend_value value; /* value */ union { struct { - ZEND_ENDIAN_LOHI_4( + ZEND_ENDIAN_LOHI_3( zend_uchar type, /* active type */ zend_uchar type_flags, - zend_uchar const_flags, - zend_uchar reserved) /* call info for EX(This) */ + union { + uint16_t call_info; /* call info for EX(This) */ + uint16_t extra; /* not further specified */ + } u) } v; uint32_t type_info; } u1; @@ -239,7 +241,7 @@ struct _zend_array { struct { ZEND_ENDIAN_LOHI_4( zend_uchar flags, - zend_uchar nApplyCount, + zend_uchar _unused, zend_uchar nIteratorsCount, zend_uchar consistency) } v; @@ -355,7 +357,7 @@ struct _zend_reference { struct _zend_ast_ref { zend_refcounted_h gc; - zend_ast *ast; + /*zend_ast ast; zend_ast follows the zend_ast_ref structure */ }; /* regular data types */ @@ -372,19 +374,18 @@ struct _zend_ast_ref { #define IS_REFERENCE 10 /* constant expressions */ -#define IS_CONSTANT 11 #define IS_CONSTANT_AST 12 -/* fake types */ -#define _IS_BOOL 13 -#define IS_CALLABLE 14 -#define IS_ITERABLE 19 -#define IS_VOID 18 - /* internal types */ -#define IS_INDIRECT 15 -#define IS_PTR 17 -#define _IS_ERROR 20 +#define IS_INDIRECT 13 +#define IS_PTR 14 +#define _IS_ERROR 15 + +/* fake types used only for type hinting (Z_TYPE(zv) can not use them) */ +#define _IS_BOOL 16 +#define IS_CALLABLE 17 +#define IS_ITERABLE 18 +#define IS_VOID 19 static zend_always_inline zend_uchar zval_get_type(const zval* pz) { return pz->u1.v.type; @@ -402,9 +403,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define Z_TYPE_FLAGS(zval) (zval).u1.v.type_flags #define Z_TYPE_FLAGS_P(zval_p) Z_TYPE_FLAGS(*(zval_p)) -#define Z_CONST_FLAGS(zval) (zval).u1.v.const_flags -#define Z_CONST_FLAGS_P(zval_p) Z_CONST_FLAGS(*(zval_p)) - #define Z_TYPE_INFO(zval) (zval).u1.type_info #define Z_TYPE_INFO_P(zval_p) Z_TYPE_INFO(*(zval_p)) @@ -432,9 +430,14 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define Z_TYPE_MASK 0xff #define Z_TYPE_FLAGS_SHIFT 8 -#define Z_CONST_FLAGS_SHIFT 16 -#define GC_REFCOUNT(p) (p)->gc.refcount +#define GC_REFCOUNT(p) zend_gc_refcount(&(p)->gc) +#define GC_SET_REFCOUNT(p, rc) zend_gc_set_refcount(&(p)->gc, rc) +#define GC_ADDREF(p) zend_gc_addref(&(p)->gc) +#define GC_DELREF(p) zend_gc_delref(&(p)->gc) +#define GC_ADDREF_EX(p, rc) zend_gc_addref_ex(&(p)->gc, rc) +#define GC_DELREF_EX(p, rc) zend_gc_delref_ex(&(p)->gc, rc) + #define GC_TYPE(p) (p)->gc.u.v.type #define GC_FLAGS(p) (p)->gc.u.v.flags #define GC_INFO(p) (p)->gc.u.v.gc_info @@ -455,78 +458,72 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define GC_INFO_SHIFT 16 #define GC_INFO_MASK 0xffff0000 -/* zval.value->gc.u.v.flags */ -#define GC_COLLECTABLE (1<<7) +/* zval.value->gc.u.v.flags (common flags) */ +#define GC_COLLECTABLE (1<<0) +#define GC_PROTECTED (1<<1) /* used for recursion detection */ +#define GC_IMMUTABLE (1<<2) /* can't be canged in place */ +#define GC_PERSISTENT (1<<3) /* allocated using malloc */ +#define GC_PERSISTENT_LOCAL (1<<4) /* persistent, but thread-local */ #define GC_ARRAY (IS_ARRAY | (GC_COLLECTABLE << GC_FLAGS_SHIFT)) #define GC_OBJECT (IS_OBJECT | (GC_COLLECTABLE << GC_FLAGS_SHIFT)) /* zval.u1.v.type_flags */ -#define IS_TYPE_CONSTANT (1<<0) -#define IS_TYPE_REFCOUNTED (1<<2) -#define IS_TYPE_COPYABLE (1<<4) +#define IS_CONSTANT_VISITED_MARK (1<<0) +#define IS_TYPE_COPYABLE (1<<1) +#define IS_TYPE_REFCOUNTED (1<<2) /* equal to ZEND_CALL_FREE_EXTRA_ARGS */ /* extended types */ #define IS_INTERNED_STRING_EX IS_STRING -#define IS_STRING_EX (IS_STRING | (( IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT)) -#define IS_ARRAY_EX (IS_ARRAY | (( IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT)) -#define IS_OBJECT_EX (IS_OBJECT | (( IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT)) -#define IS_RESOURCE_EX (IS_RESOURCE | (( IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT)) -#define IS_REFERENCE_EX (IS_REFERENCE | (( IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT)) - -#define IS_CONSTANT_EX (IS_CONSTANT | ((IS_TYPE_CONSTANT | IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT)) -#define IS_CONSTANT_AST_EX (IS_CONSTANT_AST | ((IS_TYPE_CONSTANT | IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT)) +#define IS_STRING_EX (IS_STRING | ((IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT)) +#define IS_ARRAY_EX (IS_ARRAY | ((IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE) << Z_TYPE_FLAGS_SHIFT)) +#define IS_OBJECT_EX (IS_OBJECT | ((IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT)) +#define IS_RESOURCE_EX (IS_RESOURCE | ((IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT)) +#define IS_REFERENCE_EX (IS_REFERENCE | ((IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT)) -/* zval.u1.v.const_flags */ -#define IS_CONSTANT_UNQUALIFIED 0x010 -#define IS_CONSTANT_VISITED_MARK 0x020 -#define IS_CONSTANT_CLASS 0x080 /* __CLASS__ in trait */ -#define IS_CONSTANT_IN_NAMESPACE 0x100 /* used only in opline->extended_value */ +#define IS_CONSTANT_AST_EX (IS_CONSTANT_AST | ((IS_TYPE_REFCOUNTED ) << Z_TYPE_FLAGS_SHIFT)) -#define IS_CONSTANT_VISITED(p) (Z_CONST_FLAGS_P(p) & IS_CONSTANT_VISITED_MARK) -#define MARK_CONSTANT_VISITED(p) Z_CONST_FLAGS_P(p) |= IS_CONSTANT_VISITED_MARK -#define RESET_CONSTANT_VISITED(p) Z_CONST_FLAGS_P(p) &= ~IS_CONSTANT_VISITED_MARK +#define IS_CONSTANT_VISITED(p) (Z_TYPE_FLAGS_P(p) & IS_CONSTANT_VISITED_MARK) +#define MARK_CONSTANT_VISITED(p) Z_TYPE_FLAGS_P(p) |= IS_CONSTANT_VISITED_MARK +#define RESET_CONSTANT_VISITED(p) Z_TYPE_FLAGS_P(p) &= ~IS_CONSTANT_VISITED_MARK /* string flags (zval.value->gc.u.flags) */ -#define IS_STR_PERSISTENT (1<<0) /* allocated using malloc */ -#define IS_STR_INTERNED (1<<1) /* interned string */ -#define IS_STR_PERMANENT (1<<2) /* relives request boundary */ - -#define IS_STR_CONSTANT (1<<3) /* constant index */ -#define IS_STR_CONSTANT_UNQUALIFIED (1<<4) /* the same as IS_CONSTANT_UNQUALIFIED */ +#define IS_STR_INTERNED GC_IMMUTABLE /* interned string */ +#define IS_STR_PERSISTENT GC_PERSISTENT /* allocated using malloc */ +#define IS_STR_PERMANENT (1<<5) /* relives request boundary */ /* array flags */ -#define IS_ARRAY_IMMUTABLE (1<<1) +#define IS_ARRAY_IMMUTABLE GC_IMMUTABLE +#define IS_ARRAY_PERSISTENT GC_PERSISTENT /* object flags (zval.value->gc.u.flags) */ -#define IS_OBJ_APPLY_COUNT 0x07 -#define IS_OBJ_DESTRUCTOR_CALLED (1<<3) -#define IS_OBJ_FREE_CALLED (1<<4) -#define IS_OBJ_USE_GUARDS (1<<5) -#define IS_OBJ_HAS_GUARDS (1<<6) - -#define Z_OBJ_APPLY_COUNT(zval) \ - (Z_GC_FLAGS(zval) & IS_OBJ_APPLY_COUNT) - -#define Z_OBJ_INC_APPLY_COUNT(zval) do { \ - Z_GC_FLAGS(zval) = \ - (Z_GC_FLAGS(zval) & ~IS_OBJ_APPLY_COUNT) | \ - ((Z_GC_FLAGS(zval) & IS_OBJ_APPLY_COUNT) + 1); \ +#define IS_OBJ_DESTRUCTOR_CALLED (1<<4) +#define IS_OBJ_FREE_CALLED (1<<5) +#define IS_OBJ_USE_GUARDS (1<<6) +#define IS_OBJ_HAS_GUARDS (1<<7) + +/* Recursion protection macros must be used only for arrays and objects */ +#define GC_IS_RECURSIVE(p) \ + (GC_FLAGS(p) & GC_PROTECTED) + +#define GC_PROTECT_RECURSION(p) do { \ + GC_FLAGS(p) |= GC_PROTECTED; \ } while (0) -#define Z_OBJ_DEC_APPLY_COUNT(zval) do { \ - Z_GC_FLAGS(zval) = \ - (Z_GC_FLAGS(zval) & ~IS_OBJ_APPLY_COUNT) | \ - ((Z_GC_FLAGS(zval) & IS_OBJ_APPLY_COUNT) - 1); \ +#define GC_UNPROTECT_RECURSION(p) do { \ + GC_FLAGS(p) &= ~GC_PROTECTED; \ } while (0) -#define Z_OBJ_APPLY_COUNT_P(zv) Z_OBJ_APPLY_COUNT(*(zv)) -#define Z_OBJ_INC_APPLY_COUNT_P(zv) Z_OBJ_INC_APPLY_COUNT(*(zv)) -#define Z_OBJ_DEC_APPLY_COUNT_P(zv) Z_OBJ_DEC_APPLY_COUNT(*(zv)) +#define Z_IS_RECURSIVE(zval) GC_IS_RECURSIVE(Z_COUNTED(zval)) +#define Z_PROTECT_RECURSION(zval) GC_PROTECT_RECURSION(Z_COUNTED(zval)) +#define Z_UNPROTECT_RECURSION(zval) GC_UNPROTECT_RECURSION(Z_COUNTED(zval)) +#define Z_IS_RECURSIVE_P(zv) Z_IS_RECURSIVE(*(zv)) +#define Z_PROTECT_RECURSION_P(zv) Z_PROTECT_RECURSION(*(zv)) +#define Z_UNPROTECT_RECURSION_P(zv) Z_UNPROTECT_RECURSION(*(zv)) /* All data types < IS_STRING have their constructor/destructors skipped */ -#define Z_CONSTANT(zval) ((Z_TYPE_FLAGS(zval) & IS_TYPE_CONSTANT) != 0) +#define Z_CONSTANT(zval) (Z_TYPE(zval) == IS_CONSTANT_AST) #define Z_CONSTANT_P(zval_p) Z_CONSTANT(*(zval_p)) #define Z_REFCOUNTED(zval) ((Z_TYPE_FLAGS(zval) & IS_TYPE_REFCOUNTED) != 0) @@ -545,7 +542,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define Z_OPT_TYPE(zval) (Z_TYPE_INFO(zval) & Z_TYPE_MASK) #define Z_OPT_TYPE_P(zval_p) Z_OPT_TYPE(*(zval_p)) -#define Z_OPT_CONSTANT(zval) ((Z_TYPE_INFO(zval) & (IS_TYPE_CONSTANT << Z_TYPE_FLAGS_SHIFT)) != 0) +#define Z_OPT_CONSTANT(zval) (Z_OPT_TYPE(zval) == IS_CONSTANT_AST) #define Z_OPT_CONSTANT_P(zval_p) Z_OPT_CONSTANT(*(zval_p)) #define Z_OPT_REFCOUNTED(zval) ((Z_TYPE_INFO(zval) & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0) @@ -635,7 +632,9 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define Z_AST(zval) (zval).value.ast #define Z_AST_P(zval_p) Z_AST(*(zval_p)) -#define Z_ASTVAL(zval) (zval).value.ast->ast +#define GC_AST(p) ((zend_ast*)(((char*)p) + sizeof(zend_ast_ref))) + +#define Z_ASTVAL(zval) GC_AST(Z_AST(zval)) #define Z_ASTVAL_P(zval_p) Z_ASTVAL(*(zval_p)) #define Z_INDIRECT(zval) (zval).value.zv @@ -712,17 +711,18 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { zend_string *__s = (s); \ Z_STR_P(__z) = __s; \ /* interned strings support */ \ - if (ZSTR_IS_INTERNED(__s)) { \ + if (ZSTR_IS_INTERNED(__s)) { \ Z_TYPE_INFO_P(__z) = IS_INTERNED_STRING_EX; \ } else { \ - GC_REFCOUNT(__s)++; \ + GC_ADDREF(__s); \ Z_TYPE_INFO_P(__z) = IS_STRING_EX; \ } \ } while (0) #define ZVAL_ARR(z, a) do { \ + zend_array *__arr = (a); \ zval *__z = (z); \ - Z_ARR_P(__z) = (a); \ + Z_ARR_P(__z) = __arr; \ Z_TYPE_INFO_P(__z) = IS_ARRAY_EX; \ } while (0) @@ -758,7 +758,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { zend_resource *_res = \ (zend_resource *) emalloc(sizeof(zend_resource)); \ zval *__z; \ - GC_REFCOUNT(_res) = 1; \ + GC_SET_REFCOUNT(_res, 1); \ GC_TYPE_INFO(_res) = IS_RESOURCE; \ _res->handle = (h); \ _res->type = (t); \ @@ -772,8 +772,9 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { zend_resource *_res = \ (zend_resource *) malloc(sizeof(zend_resource)); \ zval *__z; \ - GC_REFCOUNT(_res) = 1; \ - GC_TYPE_INFO(_res) = IS_RESOURCE; \ + GC_SET_REFCOUNT(_res, 1); \ + GC_TYPE_INFO(_res) = IS_RESOURCE | \ + (GC_PERSISTENT << GC_FLAGS_SHIFT); \ _res->handle = (h); \ _res->type = (t); \ _res->ptr = (p); \ @@ -791,7 +792,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define ZVAL_NEW_EMPTY_REF(z) do { \ zend_reference *_ref = \ (zend_reference *) emalloc(sizeof(zend_reference)); \ - GC_REFCOUNT(_ref) = 1; \ + GC_SET_REFCOUNT(_ref, 1); \ GC_TYPE_INFO(_ref) = IS_REFERENCE; \ Z_REF_P(z) = _ref; \ Z_TYPE_INFO_P(z) = IS_REFERENCE_EX; \ @@ -800,7 +801,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define ZVAL_NEW_REF(z, r) do { \ zend_reference *_ref = \ (zend_reference *) emalloc(sizeof(zend_reference)); \ - GC_REFCOUNT(_ref) = 1; \ + GC_SET_REFCOUNT(_ref, 1); \ GC_TYPE_INFO(_ref) = IS_REFERENCE; \ ZVAL_COPY_VALUE(&_ref->val, r); \ Z_REF_P(z) = _ref; \ @@ -810,21 +811,17 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define ZVAL_NEW_PERSISTENT_REF(z, r) do { \ zend_reference *_ref = \ (zend_reference *) malloc(sizeof(zend_reference)); \ - GC_REFCOUNT(_ref) = 1; \ - GC_TYPE_INFO(_ref) = IS_REFERENCE; \ + GC_SET_REFCOUNT(_ref, 1); \ + GC_TYPE_INFO(_ref) = IS_REFERENCE | \ + (GC_PERSISTENT << GC_FLAGS_SHIFT); \ ZVAL_COPY_VALUE(&_ref->val, r); \ Z_REF_P(z) = _ref; \ Z_TYPE_INFO_P(z) = IS_REFERENCE_EX; \ } while (0) -#define ZVAL_NEW_AST(z, a) do { \ +#define ZVAL_AST(z, ast) do { \ zval *__z = (z); \ - zend_ast_ref *_ast = \ - (zend_ast_ref *) emalloc(sizeof(zend_ast_ref)); \ - GC_REFCOUNT(_ast) = 1; \ - GC_TYPE_INFO(_ast) = IS_CONSTANT_AST; \ - _ast->ast = (a); \ - Z_AST_P(__z) = _ast; \ + Z_AST_P(__z) = ast; \ Z_TYPE_INFO_P(__z) = IS_CONSTANT_AST_EX; \ } while (0) @@ -877,24 +874,77 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define Z_TRY_ADDREF(z) Z_TRY_ADDREF_P(&(z)) #define Z_TRY_DELREF(z) Z_TRY_DELREF_P(&(z)) -static zend_always_inline uint32_t zval_refcount_p(zval* pz) { +#ifndef ZEND_RC_DEBUG +# define ZEND_RC_DEBUG 0 +#endif + +#if ZEND_RC_DEBUG +extern ZEND_API zend_bool zend_rc_debug; +# define ZEND_RC_MOD_CHECK(p) do { \ + if (zend_rc_debug) { \ + ZEND_ASSERT(!((p)->u.v.flags & GC_IMMUTABLE)); \ + ZEND_ASSERT(((p)->u.v.flags & (GC_PERSISTENT|GC_PERSISTENT_LOCAL)) != GC_PERSISTENT); \ + } \ + } while (0) +# define GC_MAKE_PERSISTENT_LOCAL(p) do { \ + GC_FLAGS(p) |= GC_PERSISTENT_LOCAL; \ + } while (0) +#else +# define ZEND_RC_MOD_CHECK(p) \ + do { } while (0) +# define GC_MAKE_PERSISTENT_LOCAL(p) \ + do { } while (0) +#endif + +static zend_always_inline uint32_t zend_gc_refcount(const zend_refcounted_h *p) { + return p->refcount; +} + +static zend_always_inline uint32_t zend_gc_set_refcount(zend_refcounted_h *p, uint32_t rc) { + p->refcount = rc; + return p->refcount; +} + +static zend_always_inline uint32_t zend_gc_addref(zend_refcounted_h *p) { + ZEND_RC_MOD_CHECK(p); + return ++(p->refcount); +} + +static zend_always_inline uint32_t zend_gc_delref(zend_refcounted_h *p) { + ZEND_RC_MOD_CHECK(p); + return --(p->refcount); +} + +static zend_always_inline uint32_t zend_gc_addref_ex(zend_refcounted_h *p, uint32_t rc) { + ZEND_RC_MOD_CHECK(p); + p->refcount += rc; + return p->refcount; +} + +static zend_always_inline uint32_t zend_gc_delref_ex(zend_refcounted_h *p, uint32_t rc) { + ZEND_RC_MOD_CHECK(p); + p->refcount -= rc; + return p->refcount; +} + +static zend_always_inline uint32_t zval_refcount_p(const zval* pz) { ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_COPYABLE_P(pz)); return GC_REFCOUNT(Z_COUNTED_P(pz)); } static zend_always_inline uint32_t zval_set_refcount_p(zval* pz, uint32_t rc) { ZEND_ASSERT(Z_REFCOUNTED_P(pz)); - return GC_REFCOUNT(Z_COUNTED_P(pz)) = rc; + return GC_SET_REFCOUNT(Z_COUNTED_P(pz), rc); } static zend_always_inline uint32_t zval_addref_p(zval* pz) { ZEND_ASSERT(Z_REFCOUNTED_P(pz)); - return ++GC_REFCOUNT(Z_COUNTED_P(pz)); + return GC_ADDREF(Z_COUNTED_P(pz)); } static zend_always_inline uint32_t zval_delref_p(zval* pz) { ZEND_ASSERT(Z_REFCOUNTED_P(pz)); - return --GC_REFCOUNT(Z_COUNTED_P(pz)); + return GC_DELREF(Z_COUNTED_P(pz)); } #if SIZEOF_SIZE_T == 4 @@ -932,7 +982,7 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) { uint32_t _t = Z_TYPE_INFO_P(_z2); \ ZVAL_COPY_VALUE_EX(_z1, _z2, _gc, _t); \ if ((_t & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0) { \ - GC_REFCOUNT(_gc)++; \ + GC_ADDREF(_gc); \ } \ } while (0) @@ -947,11 +997,31 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) { if ((_t & (IS_TYPE_COPYABLE << Z_TYPE_FLAGS_SHIFT)) != 0) { \ _zval_copy_ctor_func(_z1 ZEND_FILE_LINE_CC); \ } else { \ - GC_REFCOUNT(_gc)++; \ + GC_ADDREF(_gc); \ } \ } \ } while (0) + +/* ZVAL_COPY_OR_DUP() should be used instead of ZVAL_COPY() and ZVAL_DUP() + * in all places where the source may be a persistent zval. + */ +#define ZVAL_COPY_OR_DUP(z, v) \ + do { \ + zval *_z1 = (z); \ + const zval *_z2 = (v); \ + zend_refcounted *_gc = Z_COUNTED_P(_z2); \ + uint32_t _t = Z_TYPE_INFO_P(_z2); \ + ZVAL_COPY_VALUE_EX(_z1, _z2, _gc, _t); \ + if ((_t & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0) { \ + if (EXPECTED(!(GC_FLAGS(_gc) & GC_PERSISTENT))) { \ + GC_ADDREF(_gc); \ + } else { \ + _zval_copy_ctor_func(_z1 ZEND_FILE_LINE_CC); \ + } \ + } \ + } while (0) + #define ZVAL_DEREF(z) do { \ if (UNEXPECTED(Z_ISREF_P(z))) { \ (z) = Z_REFVAL_P(z); \ @@ -1000,10 +1070,12 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) { #define SEPARATE_STRING(zv) do { \ zval *_zv = (zv); \ if (Z_REFCOUNT_P(_zv) > 1) { \ - if (Z_REFCOUNTED_P(_zv)) { \ - Z_DELREF_P(_zv); \ - } \ - zval_copy_ctor_func(_zv); \ + zend_string *_str = Z_STR_P(_zv); \ + ZEND_ASSERT(Z_REFCOUNTED_P(_zv)); \ + ZEND_ASSERT(!ZSTR_IS_INTERNED(_str)); \ + Z_DELREF_P(_zv); \ + ZVAL_NEW_STR(_zv, zend_string_init( \ + ZSTR_VAL(_str), ZSTR_LEN(_str), 0)); \ } \ } while (0) @@ -1012,7 +1084,7 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) { zend_array *_arr = Z_ARR_P(_zv); \ if (UNEXPECTED(GC_REFCOUNT(_arr) > 1)) { \ if (Z_REFCOUNTED_P(_zv)) { \ - GC_REFCOUNT(_arr)--; \ + GC_DELREF(_arr); \ } \ ZVAL_ARR(_zv, zend_array_dup(_arr)); \ } \ diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index 6c1e235eb6..782b88c5da 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -31,11 +31,12 @@ ZEND_API void ZEND_FASTCALL _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC) { switch (GC_TYPE(p)) { - case IS_STRING: - case IS_CONSTANT: { + case IS_STRING: { zend_string *str = (zend_string*)p; CHECK_ZVAL_STRING_REL(str); - zend_string_free(str); + ZEND_ASSERT(!ZSTR_IS_INTERNED(str)); + ZEND_ASSERT(GC_REFCOUNT(str) == 0); + pefree(str, UNEXPECTED(GC_FLAGS(str) & IS_STR_PERSISTENT)); break; } case IS_ARRAY: { @@ -46,8 +47,8 @@ ZEND_API void ZEND_FASTCALL _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC case IS_CONSTANT_AST: { zend_ast_ref *ast = (zend_ast_ref*)p; - zend_ast_destroy_and_free(ast->ast); - efree_size(ast, sizeof(zend_ast_ref)); + zend_ast_destroy(GC_AST(ast)); + efree(ast); break; } case IS_OBJECT: { @@ -79,7 +80,6 @@ ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC) { switch (Z_TYPE_P(zvalue)) { case IS_STRING: - case IS_CONSTANT: CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue)); zend_string_release(Z_STR_P(zvalue)); break; @@ -110,7 +110,6 @@ ZEND_API void _zval_internal_dtor_for_ptr(zval *zvalue ZEND_FILE_LINE_DC) { switch (Z_TYPE_P(zvalue)) { case IS_STRING: - case IS_CONSTANT: CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue)); zend_string_free(Z_STR_P(zvalue)); break; @@ -168,14 +167,9 @@ ZEND_API void ZEND_FASTCALL _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC) if (EXPECTED(Z_TYPE_P(zvalue) == IS_ARRAY)) { ZVAL_ARR(zvalue, zend_array_dup(Z_ARRVAL_P(zvalue))); } else if (EXPECTED(Z_TYPE_P(zvalue) == IS_STRING)) { + ZEND_ASSERT(!ZSTR_IS_INTERNED(Z_STR_P(zvalue))); CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue)); ZVAL_NEW_STR(zvalue, zend_string_dup(Z_STR_P(zvalue), 0)); - } else if (EXPECTED(Z_TYPE_P(zvalue) == IS_CONSTANT)) { - CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue)); - Z_STR_P(zvalue) = zend_string_dup(Z_STR_P(zvalue), 0); - } else if (EXPECTED(Z_TYPE_P(zvalue) == IS_CONSTANT_AST)) { - zend_ast *copy = zend_ast_copy(Z_ASTVAL_P(zvalue)); - ZVAL_NEW_AST(zvalue, copy); } } diff --git a/Zend/zend_variables.h b/Zend/zend_variables.h index f63379003f..e26e3e03c5 100644 --- a/Zend/zend_variables.h +++ b/Zend/zend_variables.h @@ -45,7 +45,7 @@ static zend_always_inline void i_zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) { if (Z_REFCOUNTED_P(zval_ptr)) { zend_refcounted *ref = Z_COUNTED_P(zval_ptr); - if (!--GC_REFCOUNT(ref)) { + if (!GC_DELREF(ref)) { _zval_dtor_func(ref ZEND_FILE_LINE_RELAY_CC); } else { gc_check_possible_root(ref); diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index ee49c7d161..1ea6685ea6 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -155,7 +155,6 @@ typedef struct { static inline time_t FileTimeToUnixTime(const FILETIME *FileTime) { __int64 UnixTime; - long *nsec = NULL; SYSTEMTIME SystemTime; FileTimeToSystemTime(FileTime, &SystemTime); @@ -164,10 +163,6 @@ static inline time_t FileTimeToUnixTime(const FILETIME *FileTime) UnixTime -= (SECS_BETWEEN_EPOCHS * SECS_TO_100NS); - if (nsec) { - *nsec = (UnixTime % SECS_TO_100NS) * (__int64)100; - } - UnixTime /= SECS_TO_100NS; /* now convert to seconds */ if ((time_t)UnixTime != UnixTime) { @@ -176,7 +171,7 @@ static inline time_t FileTimeToUnixTime(const FILETIME *FileTime) return (time_t)UnixTime; } -CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len){ /* {{{ */ +CWD_API ssize_t php_sys_readlink(const char *link, char *target, size_t target_len){ /* {{{ */ HANDLE hFile; wchar_t *linkw = php_win32_ioutil_any_to_w(link), targetw[MAXPATHLEN]; size_t ret_len, targetw_len, offset = 0; @@ -192,8 +187,8 @@ CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len){ } hFile = CreateFileW(linkw, // file to open - GENERIC_READ, // open for reading - FILE_SHARE_READ, // share for reading + 0, // query possible attributes + PHP_WIN32_IOUTIL_DEFAULT_SHARE_MODE, NULL, // default security OPEN_EXISTING, // existing file only FILE_FLAG_BACKUP_SEMANTICS, // normal file @@ -242,7 +237,7 @@ CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len){ CloseHandle(hFile); free(linkw); - return ret_len; + return (ssize_t)ret_len; } /* }}} */ @@ -304,7 +299,13 @@ CWD_API int php_sys_stat_ex(const char *path, zend_stat_t *buf, int lstat) /* {{ REPARSE_DATA_BUFFER * pbuffer; DWORD retlength = 0; - hLink = CreateFileW(pathw, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL); + hLink = CreateFileW(pathw, + FILE_READ_ATTRIBUTES, + PHP_WIN32_IOUTIL_DEFAULT_SHARE_MODE, + NULL, + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, + NULL); if(hLink == INVALID_HANDLE_VALUE) { free(pathw); return -1; @@ -422,7 +423,7 @@ void virtual_cwd_main_cwd_init(uint8_t reinit) /* {{{ */ cwd[0] = '\0'; } - main_cwd_state.cwd_length = (int)strlen(cwd); + main_cwd_state.cwd_length = strlen(cwd); #ifdef ZEND_WIN32 if (main_cwd_state.cwd_length >= 2 && cwd[1] == ':') { cwd[0] = toupper(cwd[0]); @@ -729,10 +730,10 @@ CWD_API realpath_cache_bucket** realpath_cache_get_buckets(void) #undef LINK_MAX #define LINK_MAX 32 -static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, int use_realpath, int is_dir, int *link_is_dir) /* {{{ */ +static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, time_t *t, int use_realpath, int is_dir, int *link_is_dir) /* {{{ */ { - int i, j, save; - int directory = 0; + size_t i, j; + int directory = 0, save; #ifdef ZEND_WIN32 WIN32_FIND_DATAW dataw; HANDLE hFind = INVALID_HANDLE_VALUE; @@ -760,28 +761,31 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i while (i > start && !IS_SLASH(path[i-1])) { i--; } + assert(i < MAXPATHLEN); if (i == len || - (i == len - 1 && path[i] == '.')) { + (i + 1 == len && path[i] == '.')) { /* remove double slashes and '.' */ len = i - 1; is_dir = 1; continue; - } else if (i == len - 2 && path[i] == '.' && path[i+1] == '.') { + } else if (i + 2 == len && path[i] == '.' && path[i+1] == '.') { /* remove '..' and previous directory */ is_dir = 1; if (link_is_dir) { *link_is_dir = 1; } - if (i - 1 <= start) { + if (i <= start + 1) { return start ? start : len; } j = tsrm_realpath_r(path, start, i-1, ll, t, use_realpath, 1, NULL); - if (j > start) { + if (j > start && j != (size_t)-1) { j--; + assert(i < MAXPATHLEN); while (j > start && !IS_SLASH(path[j])) { j--; } + assert(i < MAXPATHLEN); if (!start) { /* leading '..' must not be removed in case of relative path */ if (j == 0 && path[0] == '.' && path[1] == '.' && @@ -821,7 +825,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i if ((bucket = realpath_cache_find(path, len, *t)) != NULL) { if (is_dir && !bucket->is_dir) { /* not a directory */ - return -1; + return (size_t)-1; } else { if (link_is_dir) { *link_is_dir = bucket->is_dir; @@ -836,14 +840,14 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i if (save) { pathw = php_win32_ioutil_any_to_w(path); if (!pathw) { - return -1; + return (size_t)-1; } hFind = FindFirstFileExW(pathw, FindExInfoBasic, &dataw, FindExSearchNameMatch, NULL, 0); if (INVALID_HANDLE_VALUE == hFind) { if (use_realpath == CWD_REALPATH) { /* file not found */ FREE_PATHW() - return -1; + return (size_t)-1; } /* continue resolution anyway but don't save result in the cache */ save = 0; @@ -863,7 +867,8 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i HANDLE hLink = NULL; REPARSE_DATA_BUFFER * pbuffer; DWORD retlength = 0; - int bufindex = 0, isabsolute = 0; + size_t bufindex = 0; + uint8_t isabsolute = 0; wchar_t * reparsetarget; BOOL isVolume = FALSE; #if VIRTUAL_CWD_DEBUG @@ -871,20 +876,26 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i #endif char *substitutename = NULL; size_t substitutename_len; - int substitutename_off = 0; + size_t substitutename_off = 0; wchar_t tmpsubstname[MAXPATHLEN]; if(++(*ll) > LINK_MAX) { free_alloca(tmp, use_heap); FREE_PATHW() - return -1; + return (size_t)-1; } - hLink = CreateFileW(pathw, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL); + hLink = CreateFileW(pathw, + 0, + PHP_WIN32_IOUTIL_DEFAULT_SHARE_MODE, + NULL, + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, + NULL); if(hLink == INVALID_HANDLE_VALUE) { free_alloca(tmp, use_heap); FREE_PATHW() - return -1; + return (size_t)-1; } pbuffer = (REPARSE_DATA_BUFFER *)do_alloca(MAXIMUM_REPARSE_DATA_BUFFER_SIZE, use_heap_large); @@ -892,14 +903,14 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i CloseHandle(hLink); free_alloca(tmp, use_heap); FREE_PATHW() - return -1; + return (size_t)-1; } if(!DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, pbuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &retlength, NULL)) { free_alloca(pbuffer, use_heap_large); free_alloca(tmp, use_heap); CloseHandle(hLink); FREE_PATHW() - return -1; + return (size_t)-1; } CloseHandle(hLink); @@ -913,7 +924,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i free_alloca(pbuffer, use_heap_large); free_alloca(tmp, use_heap); FREE_PATHW() - return -1; + return (size_t)-1; } #endif @@ -922,7 +933,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i free_alloca(pbuffer, use_heap_large); free_alloca(tmp, use_heap); FREE_PATHW() - return -1; + return (size_t)-1; } memmove(tmpsubstname, reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR), pbuffer->MountPointReparseBuffer.SubstituteNameLength); tmpsubstname[substitutename_len] = L'\0'; @@ -935,7 +946,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i free(printname); #endif FREE_PATHW() - return -1; + return (size_t)-1; } } else if(pbuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { @@ -947,7 +958,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i free_alloca(pbuffer, use_heap_large); free_alloca(tmp, use_heap); FREE_PATHW() - return -1; + return (size_t)-1; } #endif @@ -957,7 +968,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i free_alloca(pbuffer, use_heap_large); free_alloca(tmp, use_heap); FREE_PATHW() - return -1; + return (size_t)-1; } memmove(tmpsubstname, reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR), pbuffer->MountPointReparseBuffer.SubstituteNameLength); tmpsubstname[substitutename_len] = L'\0'; @@ -970,7 +981,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i free(printname); #endif FREE_PATHW() - return -1; + return (size_t)-1; } } else if (pbuffer->ReparseTag == IO_REPARSE_TAG_DEDUP || @@ -984,7 +995,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i free_alloca(pbuffer, use_heap_large); free_alloca(tmp, use_heap); FREE_PATHW() - return -1; + return (size_t)-1; } memcpy(substitutename, path, len + 1); substitutename_len = len; @@ -993,7 +1004,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i free_alloca(pbuffer, use_heap_large); free_alloca(tmp, use_heap); FREE_PATHW() - return -1; + return (size_t)-1; } if(isabsolute && substitutename_len > 4) { @@ -1020,7 +1031,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i if (!isVolume) { char * tmp2 = substitutename + substitutename_off; - for(bufindex = 0; bufindex < (substitutename_len - substitutename_off); bufindex++) { + for (bufindex = 0; bufindex + substitutename_off < substitutename_len; bufindex++) { *(path + bufindex) = *(tmp2 + bufindex); } @@ -1044,10 +1055,10 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i if (!((j == 3) && (path[1] == ':') && (path[2] == '\\'))) { /* use_realpath is 0 in the call below coz path is absolute*/ j = tsrm_realpath_r(path, 0, j, ll, t, 0, is_dir, &directory); - if(j < 0) { + if(j == (size_t)-1) { free_alloca(tmp, use_heap); FREE_PATHW() - return -1; + return (size_t)-1; } } } @@ -1055,17 +1066,17 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i if(i + j >= MAXPATHLEN - 1) { free_alloca(tmp, use_heap); FREE_PATHW() - return -1; + return (size_t)-1; } memmove(path+i, path, j+1); memcpy(path, tmp, i-1); path[i-1] = DEFAULT_SLASH; j = tsrm_realpath_r(path, start, i + j, ll, t, use_realpath, is_dir, &directory); - if(j < 0) { + if(j == (size_t)-1) { free_alloca(tmp, use_heap); FREE_PATHW() - return -1; + return (size_t)-1; } } directory = (dataw.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); @@ -1081,14 +1092,14 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i /* not a directory */ free_alloca(tmp, use_heap); FREE_PATHW() - return -1; + return (size_t)-1; } } #else if (save && php_sys_lstat(path, &st) < 0) { if (use_realpath == CWD_REALPATH) { /* file not found */ - return -1; + return (size_t)-1; } /* continue resolution anyway but don't save result in the cache */ save = 0; @@ -1098,30 +1109,30 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i memcpy(tmp, path, len+1); if (save && S_ISLNK(st.st_mode)) { - if (++(*ll) > LINK_MAX || (j = php_sys_readlink(tmp, path, MAXPATHLEN)) < 0) { + if (++(*ll) > LINK_MAX || (j = (size_t)php_sys_readlink(tmp, path, MAXPATHLEN)) == (size_t)-1) { /* too many links or broken symlinks */ free_alloca(tmp, use_heap); - return -1; + return (size_t)-1; } path[j] = 0; if (IS_ABSOLUTE_PATH(path, j)) { j = tsrm_realpath_r(path, 1, j, ll, t, use_realpath, is_dir, &directory); - if (j < 0) { + if (j == (size_t)-1) { free_alloca(tmp, use_heap); - return -1; + return (size_t)-1; } } else { if (i + j >= MAXPATHLEN-1) { free_alloca(tmp, use_heap); - return -1; /* buffer overflow */ + return (size_t)-1; /* buffer overflow */ } memmove(path+i, path, j+1); memcpy(path, tmp, i-1); path[i-1] = DEFAULT_SLASH; j = tsrm_realpath_r(path, start, i + j, ll, t, use_realpath, is_dir, &directory); - if (j < 0) { + if (j == (size_t)-1) { free_alloca(tmp, use_heap); - return -1; + return (size_t)-1; } } if (link_is_dir) { @@ -1136,24 +1147,24 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i if (is_dir && !directory) { /* not a directory */ free_alloca(tmp, use_heap); - return -1; + return (size_t)-1; } } #endif - if (i - 1 <= start) { + if (i <= start + 1) { j = start; } else { /* some leading directories may be unaccessable */ j = tsrm_realpath_r(path, start, i-1, ll, t, save ? CWD_FILEPATH : use_realpath, 1, NULL); - if (j > start) { + if (j > start && j != (size_t)-1) { path[j++] = DEFAULT_SLASH; } } #ifdef ZEND_WIN32 - if (j < 0 || j + len - i >= MAXPATHLEN-1) { + if (j == (size_t)-1 || j + len >= MAXPATHLEN - 1 + i) { free_alloca(tmp, use_heap); FREE_PATHW() - return -1; + return (size_t)-1; } if (save) { size_t sz; @@ -1161,9 +1172,9 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i if (!tmp_path) { free_alloca(tmp, use_heap); FREE_PATHW() - return -1; + return (size_t)-1; } - i = (int)sz; + i = sz; memcpy(path+j, tmp_path, i+1); free(tmp_path); j += i; @@ -1174,9 +1185,9 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i } } #else - if (j < 0 || j + len - i >= MAXPATHLEN-1) { + if (j == (size_t)-1 || j + len >= MAXPATHLEN - 1 + i) { free_alloca(tmp, use_heap); - return -1; + return (size_t)-1; } memcpy(path+j, tmp+i, len-i+1); j += (len-i); @@ -1198,20 +1209,54 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i } /* }}} */ +#ifdef ZEND_WIN32 +static size_t tsrm_win32_realpath_quick(char *path, size_t len, time_t *t) /* {{{ */ +{ + char tmp_resolved_path[MAXPATHLEN]; + int tmp_resolved_path_len; + BY_HANDLE_FILE_INFORMATION info; + realpath_cache_bucket *bucket; + + if (!*t) { + *t = time(0); + } + + if (CWDG(realpath_cache_size_limit) && (bucket = realpath_cache_find(path, len, *t)) != NULL) { + memcpy(path, bucket->realpath, bucket->realpath_len + 1); + return bucket->realpath_len; + } + + if (!php_win32_ioutil_realpath_ex0(path, tmp_resolved_path, &info)) { + DWORD err = GetLastError(); + SET_ERRNO_FROM_WIN32_CODE(err); + return (size_t)-1; + } + + tmp_resolved_path_len = strlen(tmp_resolved_path); + if (CWDG(realpath_cache_size_limit)) { + realpath_cache_add(path, len, tmp_resolved_path, tmp_resolved_path_len, info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY, *t); + } + memmove(path, tmp_resolved_path, tmp_resolved_path_len + 1); + + return tmp_resolved_path_len; +} +/* }}} */ +#endif + /* Resolve path relatively to state and put the real path into state */ /* returns 0 for ok, 1 for error */ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath) /* {{{ */ { - int path_length = (int)strlen(path); - char resolved_path[MAXPATHLEN]; - int start = 1; + size_t path_length = strlen(path); + char resolved_path[MAXPATHLEN] = {0}; + size_t start = 1; int ll = 0; time_t t; int ret; int add_slash; void *tmp; - if (path_length <= 0 || path_length >= MAXPATHLEN-1) { + if (!path_length || path_length >= MAXPATHLEN-1) { #ifdef ZEND_WIN32 _set_errno(EINVAL); #else @@ -1233,7 +1278,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func start = 0; memcpy(resolved_path , path, path_length + 1); } else { - int state_cwd_length = state->cwd_length; + size_t state_cwd_length = state->cwd_length; #ifdef ZEND_WIN32 if (IS_SLASH(path[0])) { @@ -1325,9 +1370,29 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func add_slash = (use_realpath != CWD_REALPATH) && path_length > 0 && IS_SLASH(resolved_path[path_length-1]); t = CWDG(realpath_cache_ttl) ? 0 : -1; +#ifdef ZEND_WIN32 + if (CWD_EXPAND != use_realpath) { + size_t tmp_len = tsrm_win32_realpath_quick(resolved_path, path_length, &t); + if ((size_t)-1 != tmp_len) { + path_length = tmp_len; + } else { + DWORD err = GetLastError(); + /* The access denied error can mean something completely else, + fallback to complicated way. */ + if (CWD_REALPATH == use_realpath && ERROR_ACCESS_DENIED != err) { + SET_ERRNO_FROM_WIN32_CODE(err); + return 1; + } + path_length = tsrm_realpath_r(resolved_path, start, path_length, &ll, &t, use_realpath, 0, NULL); + } + } else { + path_length = tsrm_realpath_r(resolved_path, start, path_length, &ll, &t, use_realpath, 0, NULL); + } +#else path_length = tsrm_realpath_r(resolved_path, start, path_length, &ll, &t, use_realpath, 0, NULL); +#endif - if (path_length < 0) { + if (path_length == (size_t)-1) { errno = ENOENT; return 1; } @@ -1335,6 +1400,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func if (!start && !path_length) { resolved_path[path_length++] = '.'; } + if (add_slash && path_length && !IS_SLASH(resolved_path[path_length-1])) { if (path_length >= MAXPATHLEN-1) { return -1; @@ -1443,7 +1509,7 @@ CWD_API char *virtual_realpath(const char *path, char *real_path) /* {{{ */ } if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)==0) { - int len = new_state.cwd_length>MAXPATHLEN-1?MAXPATHLEN-1:new_state.cwd_length; + size_t len = new_state.cwd_length>MAXPATHLEN-1?MAXPATHLEN-1:new_state.cwd_length; memcpy(real_path, new_state.cwd, len); real_path[len] = '\0'; @@ -1907,7 +1973,7 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path) /* {{{ */ } else if (!IS_ABSOLUTE_PATH(path, strlen(path)) && VCWD_GETCWD(cwd, MAXPATHLEN)) { new_state.cwd = estrdup(cwd); - new_state.cwd_length = (int)strlen(cwd); + new_state.cwd_length = strlen(cwd); } else { new_state.cwd = (char*)emalloc(1); new_state.cwd[0] = '\0'; @@ -1920,7 +1986,7 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path) /* {{{ */ } if (real_path) { - int copy_len = new_state.cwd_length>MAXPATHLEN-1 ? MAXPATHLEN-1 : new_state.cwd_length; + size_t copy_len = new_state.cwd_length>MAXPATHLEN-1 ? MAXPATHLEN-1 : new_state.cwd_length; memcpy(real_path, new_state.cwd, copy_len); real_path[copy_len] = '\0'; efree(new_state.cwd); diff --git a/Zend/zend_virtual_cwd.h b/Zend/zend_virtual_cwd.h index dee87c0a36..bade843634 100644 --- a/Zend/zend_virtual_cwd.h +++ b/Zend/zend_virtual_cwd.h @@ -121,7 +121,7 @@ typedef unsigned short mode_t; CWD_API int php_sys_stat_ex(const char *path, zend_stat_t *buf, int lstat); # define php_sys_stat(path, buf) php_sys_stat_ex(path, buf, 0) # define php_sys_lstat(path, buf) php_sys_stat_ex(path, buf, 1) -CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len); +CWD_API ssize_t php_sys_readlink(const char *link, char *target, size_t target_len); #else # define php_sys_stat stat # define php_sys_lstat lstat @@ -132,7 +132,7 @@ CWD_API int php_sys_readlink(const char *link, char *target, size_t target_len); typedef struct _cwd_state { char *cwd; - int cwd_length; + size_t cwd_length; } cwd_state; typedef int (*verify_path_func)(const cwd_state *); @@ -160,21 +160,6 @@ CWD_API int virtual_rmdir(const char *pathname); CWD_API DIR *virtual_opendir(const char *pathname); CWD_API FILE *virtual_popen(const char *command, const char *type); CWD_API int virtual_access(const char *pathname, int mode); -#if defined(ZEND_WIN32) -/* these are not defined in win32 headers */ -#ifndef W_OK -#define W_OK 0x02 -#endif -#ifndef R_OK -#define R_OK 0x04 -#endif -#ifndef X_OK -#define X_OK 0x01 -#endif -#ifndef F_OK -#define F_OK 0x00 -#endif -#endif #if HAVE_UTIME CWD_API int virtual_utime(const char *filename, struct utimbuf *buf); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index dc52e00bc2..01cd3435c3 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -111,7 +111,7 @@ ZEND_VM_HANDLER(2, ZEND_SUB, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(3, ZEND_MUL, CONST|TMPVAR|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(3, ZEND_MUL, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(COMMUTATIVE)) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -297,38 +297,36 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV) zend_string *op2_str = Z_STR_P(op2); zend_string *str; - do { - if (OP1_TYPE != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - FREE_OP1(); - break; - } - } - if (OP2_TYPE != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - FREE_OP1(); - break; - } + if (OP1_TYPE != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (OP2_TYPE == IS_CONST || OP2_TYPE == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; + FREE_OP1(); + } else if (OP2_TYPE != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } + FREE_OP2(); + } else if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + FREE_OP2(); + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); FREE_OP1(); - } while (0); - FREE_OP2(); + FREE_OP2(); + } ZEND_VM_NEXT_OPCODE(); } else { SAVE_OPLINE(); @@ -346,7 +344,7 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV) } } -ZEND_VM_HANDLER(15, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) +ZEND_VM_HANDLER(15, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV, SPEC(COMMUTATIVE)) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -364,7 +362,7 @@ ZEND_VM_HANDLER(15, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(16, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) +ZEND_VM_HANDLER(16, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV, SPEC(COMMUTATIVE)) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -382,7 +380,7 @@ ZEND_VM_HANDLER(16, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(17, ZEND_IS_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(17, ZEND_IS_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(COMMUTATIVE)) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -411,17 +409,7 @@ ZEND_VM_HANDLER(17, ZEND_IS_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV) } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); FREE_OP1(); FREE_OP2(); } else { @@ -450,7 +438,7 @@ ZEND_VM_HANDLER(17, ZEND_IS_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(18, ZEND_IS_NOT_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(18, ZEND_IS_NOT_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(COMMUTATIVE)) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -479,17 +467,7 @@ ZEND_VM_HANDLER(18, ZEND_IS_NOT_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV) } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 0; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 1; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0); - } + result = !zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); FREE_OP1(); FREE_OP2(); } else { @@ -633,7 +611,7 @@ ZEND_VM_HANDLER(170, ZEND_SPACESHIP, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(9, ZEND_BW_OR, CONST|TMPVAR|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(9, ZEND_BW_OR, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(COMMUTATIVE)) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -660,7 +638,7 @@ ZEND_VM_HANDLER(9, ZEND_BW_OR, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(10, ZEND_BW_AND, CONST|TMPVAR|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(10, ZEND_BW_AND, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(COMMUTATIVE)) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -687,7 +665,7 @@ ZEND_VM_HANDLER(10, ZEND_BW_AND, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(11, ZEND_BW_XOR, CONST|TMPVAR|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(11, ZEND_BW_XOR, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(COMMUTATIVE)) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -714,7 +692,7 @@ ZEND_VM_HANDLER(11, ZEND_BW_XOR, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(14, ZEND_BOOL_XOR, CONST|TMPVAR|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(14, ZEND_BOOL_XOR, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(COMMUTATIVE)) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -806,7 +784,7 @@ ZEND_VM_HELPER(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, property = GET_OP2_ZVAL_PTR(BP_VAR_R); do { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -830,7 +808,6 @@ ZEND_VM_HELPER(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); binary_op(zptr, zptr, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -863,6 +840,7 @@ ZEND_VM_HELPER(zend_binary_assign_op_dim_helper, VAR|CV, CONST|TMPVAR|UNUSED|CV, ZEND_VM_C_LABEL(assign_dim_op_array): SEPARATE_ARRAY(container); ZEND_VM_C_LABEL(assign_dim_op_new_array): + dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); if (OP2_TYPE == IS_UNUSED) { var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { @@ -870,8 +848,6 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array): ZEND_VM_C_GOTO(assign_dim_op_ret_null); } } else { - dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); - if (OP2_TYPE == IS_CONST) { var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); } else { @@ -881,10 +857,9 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array): ZEND_VM_C_GOTO(assign_dim_op_ret_null); } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); binary_op(var_ptr, var_ptr, value); @@ -900,15 +875,14 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array): } else if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); ZEND_VM_C_LABEL(assign_dim_op_convert_to_array): - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(container, zend_new_array(8)); ZEND_VM_C_GOTO(assign_dim_op_new_array); } dim = GET_OP2_ZVAL_PTR(BP_VAR_R); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC); } else { if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { @@ -930,7 +904,7 @@ ZEND_VM_C_LABEL(assign_dim_op_ret_null): ZVAL_NULL(EX_VAR(opline->result.var)); } } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); } } @@ -957,7 +931,6 @@ ZEND_VM_HELPER(zend_binary_assign_op_simple_helper, VAR|CV, CONST|TMPVAR|CV, bin } } else { ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); binary_op(var_ptr, var_ptr, value); @@ -1098,7 +1071,6 @@ ZEND_VM_HELPER(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); if (inc) { increment_function(zptr); @@ -1175,8 +1147,7 @@ ZEND_VM_HELPER(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, } } else { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); - zval_opt_copy_ctor(zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); if (inc) { increment_function(zptr); } else { @@ -1232,7 +1203,6 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY, SPEC(RETVAL)) var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); increment_function(var_ptr); @@ -1272,7 +1242,6 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY, SPEC(RETVAL)) var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); decrement_function(var_ptr); @@ -1308,8 +1277,7 @@ ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY) var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - zval_opt_copy_ctor(var_ptr); + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); increment_function(var_ptr); @@ -1341,8 +1309,7 @@ ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY) var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - zval_opt_copy_ctor(var_ptr); + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); decrement_function(var_ptr); @@ -1366,7 +1333,7 @@ ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMPVAR|CV, ANY) zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); } } else { - zend_string *str = _zval_get_string_func(z); + zend_string *str = zval_get_string_func(z); if (ZSTR_LEN(str) != 0) { zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); @@ -1386,7 +1353,7 @@ ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type) zend_free_op free_op1; zval *varname; zval *retval; - zend_string *name; + zend_string *name, *tmp_name; HashTable *target_symbol_table; SAVE_OPLINE(); @@ -1396,16 +1363,16 @@ ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type) name = Z_STR_P(varname); } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { name = Z_STR_P(varname); - zend_string_addref(name); + tmp_name = NULL; } else { if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { GET_OP1_UNDEF_CV(varname, BP_VAR_R); } - name = zval_get_string(varname); + name = zval_get_tmp_string(varname, &tmp_name); } target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); - retval = zend_hash_find(target_symbol_table, name); + retval = zend_hash_find_ex(target_symbol_table, name, OP1_TYPE == IS_CONST); if (retval == NULL) { if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { zval *result; @@ -1442,7 +1409,7 @@ ZEND_VM_C_LABEL(fetch_this): EMPTY_SWITCH_DEFAULT_CASE() } if (OP1_TYPE != IS_CONST) { - zend_string_release(name); + zend_tmp_string_release(tmp_name); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -1494,7 +1461,7 @@ ZEND_VM_C_LABEL(fetch_this): } if (OP1_TYPE != IS_CONST) { - zend_string_release(name); + zend_tmp_string_release(tmp_name); } ZEND_ASSERT(retval != NULL); @@ -1552,7 +1519,7 @@ ZEND_VM_HELPER(zend_fetch_static_prop_helper, CONST|TMPVAR|CV, UNUSED|CONST|VAR, SAVE_OPLINE(); varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); - retval = zend_fetch_static_property_address(varname, OP1_TYPE, opline->op2, OP2_TYPE, type EXECUTE_DATA_CC); + retval = zend_fetch_static_property_address(varname, OP1_TYPE, opline->op2, OP2_TYPE, type EXECUTE_DATA_CC OPLINE_CC); if (UNEXPECTED(retval == NULL)) { if (EG(exception)) { @@ -1700,40 +1667,28 @@ ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, NUM) { USE_OPLINE - zval *container; - zend_free_op free_op1, free_op2; - - SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); FREE_UNFETCHED_OP2(); FREE_UNFETCHED_OP1(); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE EXECUTE_DATA_CC); - if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - FREE_OP2(); - FREE_OP1_VAR_PTR(); + ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_DIM_W); } else { if (OP2_TYPE == IS_UNUSED) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use [] for reading"); FREE_UNFETCHED_OP2(); FREE_UNFETCHED_OP1(); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE EXECUTE_DATA_CC); - FREE_OP2(); - FREE_OP1(); + ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_DIM_R); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMPVAR|CV) @@ -1754,33 +1709,41 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) { USE_OPLINE zend_free_op free_op1; zval *container; zend_free_op free_op2; zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); - container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R); + container = GET_OP1_OBJ_ZVAL_PTR_UNDEF(BP_VAR_R); if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper); } - offset = GET_OP2_ZVAL_PTR(BP_VAR_R); + offset = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); if (OP1_TYPE == IS_CONST || (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - ZEND_VM_C_GOTO(fetch_obj_r_no_object); + do { + if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - } else { ZEND_VM_C_GOTO(fetch_obj_r_no_object); - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -1788,23 +1751,47 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (OP2_TYPE == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if (OP2_TYPE == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } } } + } else if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (UNEXPECTED(zobj->handlers->read_property == NULL)) { @@ -1815,7 +1802,7 @@ ZEND_VM_C_LABEL(fetch_obj_r_no_object): zend_string_release(property_name); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); @@ -1882,6 +1869,7 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR zval *container; zend_free_op free_op2; zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS); @@ -1890,18 +1878,19 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper); } - offset = GET_OP2_ZVAL_PTR(BP_VAR_R); + offset = GET_OP2_ZVAL_PTR(BP_VAR_R); if (OP1_TYPE == IS_CONST || (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - ZEND_VM_C_GOTO(fetch_obj_is_no_object); + do { + if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } } - } else { ZEND_VM_C_GOTO(fetch_obj_is_no_object); - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -1909,21 +1898,43 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (OP2_TYPE == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if (OP2_TYPE == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } } } } @@ -1933,7 +1944,7 @@ ZEND_VM_C_LABEL(fetch_obj_is_no_object): ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -1949,34 +1960,19 @@ ZEND_VM_C_LABEL(fetch_obj_is_no_object): ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, NUM) { USE_OPLINE - zval *container; if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1, free_op2; - zval *property; - - SAVE_OPLINE(); - container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); - - if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_DISPATCH_TO_HELPER(zend_this_not_in_object_context_helper); - } if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); FREE_UNFETCHED_OP2(); - FREE_OP1_VAR_PTR(); + FREE_UNFETCHED_OP1(); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - property = GET_OP2_ZVAL_PTR(BP_VAR_R); - zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - FREE_OP2(); - if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - FREE_OP1_VAR_PTR(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_OBJ_W); } else { ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_OBJ_R); } @@ -2006,7 +2002,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(98, ZEND_FETCH_LIST_R, CONST|TMPVAR|CV, CONST|TMPVAR|CV) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -2014,7 +2010,32 @@ ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST|TMPVAR|CV) SAVE_OPLINE(); container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); - zend_fetch_dimension_address_read_LIST(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R) EXECUTE_DATA_CC); + zend_fetch_dimension_address_LIST_r(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R) EXECUTE_DATA_CC); + FREE_OP2(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +ZEND_VM_HANDLER(198, ZEND_FETCH_LIST_W, VAR|CV, CONST|TMPVAR|CV) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *retval, *container, *dim; + + SAVE_OPLINE(); + retval = EX_VAR(opline->result.var); + container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); + dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + + if (OP1_TYPE == IS_VAR + && Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT + && UNEXPECTED(!Z_ISREF_P(container)) + ) { + zend_error(E_NOTICE, "Attempting to set reference to non referenceable value"); + zend_fetch_dimension_address_LIST_r(retval, container, dim EXECUTE_DATA_CC); + } else { + zend_fetch_dimension_address_LIST_w(retval, container, dim EXECUTE_DATA_CC); + } + FREE_OP2(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -2047,7 +2068,7 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, SPEC( (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -2079,11 +2100,11 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, SPEC( if (OP2_TYPE == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { ZEND_VM_C_LABEL(fast_assign_obj): @@ -2097,11 +2118,11 @@ ZEND_VM_C_LABEL(fast_assign_obj): if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { ZEND_VM_C_GOTO(fast_assign_obj); } @@ -2120,24 +2141,20 @@ ZEND_VM_C_LABEL(fast_assign_obj): if (Z_ISREF_P(value)) { if (OP_DATA_TYPE == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (OP_DATA_TYPE == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (OP_DATA_TYPE == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -2247,8 +2264,7 @@ ZEND_VM_C_LABEL(try_assign_dim_array): FREE_OP_DATA(); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); ZEND_VM_C_GOTO(try_assign_dim_array); } else { if (OP1_TYPE != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { @@ -2372,7 +2388,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) #else if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { #endif - GC_REFCOUNT(object)--; + GC_DELREF(object); zend_object_store_ctor_failed(object); } OBJ_RELEASE(object); @@ -2403,7 +2419,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) #else if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { #endif - GC_REFCOUNT(object)--; + GC_DELREF(object); zend_object_store_ctor_failed(object); } OBJ_RELEASE(object); @@ -2689,38 +2705,36 @@ ZEND_VM_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV) zend_string *op2_str = Z_STR_P(op2); zend_string *str; - do { - if (OP1_TYPE != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - FREE_OP1(); - break; - } - } - if (OP2_TYPE != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - FREE_OP1(); - break; - } + if (OP1_TYPE != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (OP2_TYPE == IS_CONST || OP2_TYPE == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; + FREE_OP1(); + } else if (OP2_TYPE != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } + FREE_OP2(); + } else if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + FREE_OP2(); + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); FREE_OP1(); - } while (0); - FREE_OP2(); + FREE_OP2(); + } ZEND_VM_NEXT_OPCODE(); } @@ -2733,7 +2747,7 @@ ZEND_VM_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV) if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - op1_str = _zval_get_string_func(op1); + op1_str = zval_get_string_func(op1); } if (OP2_TYPE == IS_CONST) { op2_str = Z_STR_P(op2); @@ -2743,13 +2757,15 @@ ZEND_VM_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV) if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { GET_OP2_UNDEF_CV(op2, BP_VAR_R); } - op2_str = _zval_get_string_func(op2); + op2_str = zval_get_string_func(op2); } do { if (OP1_TYPE != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { if (OP2_TYPE == IS_CONST) { - zend_string_addref(op2_str); + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } } ZVAL_STR(EX_VAR(opline->result.var), op2_str); zend_string_release(op1_str); @@ -2759,7 +2775,9 @@ ZEND_VM_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV) if (OP2_TYPE != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { if (OP1_TYPE == IS_CONST) { - zend_string_addref(op1_str); + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } } ZVAL_STR(EX_VAR(opline->result.var), op1_str); zend_string_release(op2_str); @@ -2793,7 +2811,10 @@ ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMPVAR|CV, NUM) rope = (zend_string**)EX_VAR(opline->result.var); if (OP2_TYPE == IS_CONST) { var = GET_OP2_ZVAL_PTR(BP_VAR_R); - rope[0] = zend_string_copy(Z_STR_P(var)); + rope[0] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); + } } else { var = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { @@ -2807,7 +2828,7 @@ ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMPVAR|CV, NUM) if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { GET_OP2_UNDEF_CV(var, BP_VAR_R); } - rope[0] = _zval_get_string_func(var); + rope[0] = zval_get_string_func(var); FREE_OP2(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -2826,7 +2847,10 @@ ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMPVAR|CV, NUM) rope = (zend_string**)EX_VAR(opline->op1.var); if (OP2_TYPE == IS_CONST) { var = GET_OP2_ZVAL_PTR(BP_VAR_R); - rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); + rope[opline->extended_value] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); + } } else { var = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { @@ -2840,7 +2864,7 @@ ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMPVAR|CV, NUM) if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { GET_OP2_UNDEF_CV(var, BP_VAR_R); } - rope[opline->extended_value] = _zval_get_string_func(var); + rope[opline->extended_value] = zval_get_string_func(var); FREE_OP2(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -2861,7 +2885,10 @@ ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV, NUM) rope = (zend_string**)EX_VAR(opline->op1.var); if (OP2_TYPE == IS_CONST) { var = GET_OP2_ZVAL_PTR(BP_VAR_R); - rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); + rope[opline->extended_value] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); + } } else { var = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { @@ -2875,7 +2902,7 @@ ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV, NUM) if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { GET_OP2_UNDEF_CV(var, BP_VAR_R); } - rope[opline->extended_value] = _zval_get_string_func(var); + rope[opline->extended_value] = zval_get_string_func(var); FREE_OP2(); if (UNEXPECTED(EG(exception))) { for (i = 0; i <= opline->extended_value; i++) { @@ -2919,7 +2946,7 @@ ZEND_VM_C_LABEL(try_class_name): zend_class_entry *ce = CACHED_PTR(Z_CACHE_SLOT_P(class_name)); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(class_name), EX_CONSTANT(opline->op2) + 1, opline->extended_value); + ce = zend_fetch_class_by_name(Z_STR_P(class_name), RT_CONSTANT(opline, opline->op2) + 1, opline->extended_value); CACHE_PTR(Z_CACHE_SLOT_P(class_name), ce); } Z_CE_P(EX_VAR(opline->result.var)) = ce; @@ -3030,7 +3057,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, CONST|T } /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); @@ -3056,7 +3083,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, CONST|T } else if (OP1_TYPE & (IS_VAR|IS_TMP_VAR|IS_CV)) { /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(obj)++; /* For $this pointer */ + GC_ADDREF(obj); /* For $this pointer */ } FREE_OP2(); @@ -3087,14 +3114,14 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, if (OP1_TYPE == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else if (OP1_TYPE == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -3109,12 +3136,12 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, if (OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { /* nothing to do */ } else if (OP1_TYPE != IS_CONST && OP2_TYPE == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); } else if (OP2_TYPE != IS_UNUSED) { zend_free_op free_op2; @@ -3143,7 +3170,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { @@ -3236,10 +3263,10 @@ ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM) zval *function_name, *func; zend_execute_data *call; - function_name = (zval*)EX_CONSTANT(opline->op2); + function_name = (zval*)RT_CONSTANT(opline, opline->op2); fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name)); if (UNEXPECTED(fbc == NULL)) { - func = zend_hash_find(EG(function_table), Z_STR_P(function_name+1)); + func = zend_hash_find_ex(EG(function_table), Z_STR_P(function_name+1), 1); if (UNEXPECTED(func == NULL)) { SAVE_OPLINE(); zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(function_name)); @@ -3349,14 +3376,14 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM) if (func->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT); - GC_REFCOUNT((zend_object*)func->common.prototype)++; + GC_ADDREF((zend_object*)func->common.prototype); call_info |= ZEND_CALL_CLOSURE; if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { call_info |= ZEND_CALL_FAKE_CLOSURE; } } else if (object) { call_info |= ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(object)++; /* For $this pointer */ + GC_ADDREF(object); /* For $this pointer */ } FREE_OP2(); @@ -3374,7 +3401,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM) init_func_run_time_cache(&func->op_array); } } else { - zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(EX_CONSTANT(opline->op1)), error); + zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); efree(error); FREE_OP2(); if (UNEXPECTED(EG(exception))) { @@ -3401,21 +3428,21 @@ ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM) zend_function *fbc; zend_execute_data *call; - func_name = EX_CONSTANT(opline->op2) + 1; - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + func_name = RT_CONSTANT(opline, opline->op2) + 1; + fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); if (UNEXPECTED(fbc == NULL)) { - func = zend_hash_find(EG(function_table), Z_STR_P(func_name)); + func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name), 1); if (func == NULL) { func_name++; - func = zend_hash_find(EG(function_table), Z_STR_P(func_name)); + func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name), 1); if (UNEXPECTED(func == NULL)) { SAVE_OPLINE(); - zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); HANDLE_EXCEPTION(); } } fbc = Z_FUNC_P(func); - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), fbc); if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -3440,7 +3467,7 @@ ZEND_VM_HOT_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM) fbc = CACHED_PTR(Z_CACHE_SLOT_P(fname)); if (UNEXPECTED(fbc == NULL)) { - func = zend_hash_find(EG(function_table), Z_STR_P(fname)); + func = zend_hash_find_ex(EG(function_table), Z_STR_P(fname), 1); if (UNEXPECTED(func == NULL)) { SAVE_OPLINE(); zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(fname)); @@ -3482,11 +3509,12 @@ ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL)) fbc->internal_function.handler(call, ret); #if ZEND_DEBUG - ZEND_ASSERT( - EG(exception) || !call->func || - !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); - ZEND_ASSERT(!Z_ISREF_P(ret)); + if (!EG(exception) && call->func) { + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); + } #endif EG(current_execute_data) = execute_data; @@ -3523,9 +3551,11 @@ ZEND_VM_HOT_HANDLER(130, ZEND_DO_UCALL, ANY, ANY, SPEC(RETVAL)) } call->prev_execute_data = execute_data; - i_init_func_execute_data(call, &fbc->op_array, ret); + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + LOAD_OPLINE(); - ZEND_VM_ENTER(); + ZEND_VM_ENTER_EX(); } ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL)) @@ -3546,9 +3576,11 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL)) } call->prev_execute_data = execute_data; - i_init_func_execute_data(call, &fbc->op_array, ret); + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + LOAD_OPLINE(); - ZEND_VM_ENTER(); + ZEND_VM_ENTER_EX(); } else { zval retval; ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); @@ -3634,8 +3666,6 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL)) } } - LOAD_OPLINE(); - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { ret = NULL; if (RETURN_VALUE_USED(opline)) { @@ -3644,11 +3674,15 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL)) } call->prev_execute_data = execute_data; - i_init_func_execute_data(call, &fbc->op_array, ret); + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC); if (EXPECTED(zend_execute_ex == execute_ex)) { - ZEND_VM_ENTER(); + LOAD_OPLINE(); + ZEND_VM_ENTER_EX(); } else { + execute_data = EX(prev_execute_data); + LOAD_OPLINE(); ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); zend_execute_ex(call); } @@ -3715,7 +3749,7 @@ ZEND_VM_C_LABEL(fcall_end): #else if (UNEXPECTED(EG(exception) != NULL) && (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR)) { #endif - GC_REFCOUNT(object)--; + GC_DELREF(object); zend_object_store_ctor_failed(object); } OBJ_RELEASE(object); @@ -3833,7 +3867,7 @@ ZEND_VM_HOT_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY) retval_ptr = Z_REFVAL_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { Z_ADDREF_P(retval_ptr); @@ -3871,7 +3905,7 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC) ZVAL_NEW_REF(EX(return_value), retval_ptr); if (OP1_TYPE == IS_CONST) { - if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr); + Z_TRY_ADDREF_P(retval_ptr); } } break; @@ -4008,7 +4042,7 @@ ZEND_VM_HANDLER(161, ZEND_GENERATOR_RETURN, CONST|TMP|VAR|CV, ANY) retval = Z_REFVAL_P(retval); ZVAL_COPY_VALUE(&generator->retval, retval); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(retval)) { Z_ADDREF_P(retval); @@ -4056,7 +4090,7 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY) zend_exception_save(); if (OP1_TYPE != IS_TMP_VAR) { - if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value); + Z_TRY_ADDREF_P(value); } zend_throw_exception_object(value); @@ -4079,11 +4113,11 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, JMP_ADDR) ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); ZEND_VM_CONTINUE(); } - catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(catch_ce == NULL)) { - catch_ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); + catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), catch_ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), catch_ce); } ce = EG(exception)->ce; @@ -4112,7 +4146,7 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, JMP_ADDR) zval_ptr_dtor(ex); ZVAL_OBJ(ex, EG(exception)); if (UNEXPECTED(EG(exception) != exception)) { - GC_REFCOUNT(EG(exception))++; + GC_ADDREF(EG(exception)); HANDLE_EXCEPTION(); } else { EG(exception) = NULL; @@ -4194,7 +4228,7 @@ ZEND_VM_HOT_HANDLER(117, ZEND_SEND_VAR, VAR|CV, NUM) varptr = Z_REFVAL_P(varptr); ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(arg)) { Z_ADDREF_P(arg); @@ -4331,7 +4365,7 @@ ZEND_VM_C_LABEL(send_var_by_ref): varptr = Z_REFVAL_P(varptr); ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(arg)) { Z_ADDREF_P(arg); @@ -4471,7 +4505,7 @@ ZEND_VM_C_LABEL(send_again): if (Z_ISREF_P(arg)) { ZVAL_DUP(arg, Z_REFVAL_P(arg)); } else { - if (Z_REFCOUNTED_P(arg)) Z_ADDREF_P(arg); + Z_TRY_ADDREF_P(arg); } zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1); @@ -4677,11 +4711,11 @@ ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT, NUM, CONST) arg_num = opline->op1.num; param = _get_zval_ptr_cv_undef_BP_VAR_W(opline->result.var EXECUTE_DATA_CC); if (arg_num > EX_NUM_ARGS()) { - ZVAL_COPY(param, EX_CONSTANT(opline->op2)); - if (Z_OPT_CONSTANT_P(param)) { + ZVAL_COPY(param, RT_CONSTANT(opline, opline->op2)); + if (Z_OPT_TYPE_P(param) == IS_CONSTANT_AST) { SAVE_OPLINE(); if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) { - zval_ptr_dtor(param); + zval_ptr_dtor_nogc(param); ZVAL_UNDEF(param); HANDLE_EXCEPTION(); } @@ -4689,7 +4723,7 @@ ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT, NUM, CONST) } if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { - zval *default_value = EX_CONSTANT(opline->op2); + zval *default_value = RT_CONSTANT(opline, opline->op2); SAVE_OPLINE(); if (UNEXPECTED(!zend_verify_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(Z_CACHE_SLOT_P(default_value))) || EG(exception))) { @@ -4735,7 +4769,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, ANY) } } ZEND_HASH_FILL_END(); } else { - array_init(params); + ZVAL_EMPTY_ARRAY(params); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -4795,17 +4829,7 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV) } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); FREE_OP2(); } else { break; @@ -4842,15 +4866,15 @@ ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, ANY, NUM) SAVE_OPLINE(); if (OP1_TYPE == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else if (OP1_TYPE == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -4987,42 +5011,34 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED, CONST, CONST_FETCH) USE_OPLINE zend_constant *c; - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - } else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op2) + 1, opline->extended_value)) == NULL) { + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { + c = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + } else if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->extended_value)) == NULL) { SAVE_OPLINE(); if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { - char *actual = (char *)zend_memrchr(Z_STRVAL_P(EX_CONSTANT(opline->op2)), '\\', Z_STRLEN_P(EX_CONSTANT(opline->op2))); + char *actual = (char *)zend_memrchr(Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)), '\\', Z_STRLEN_P(RT_CONSTANT(opline, opline->op2))); if (!actual) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(EX_CONSTANT(opline->op2))); + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(RT_CONSTANT(opline, opline->op2))); } else { actual++; ZVAL_STRINGL(EX_VAR(opline->result.var), - actual, Z_STRLEN_P(EX_CONSTANT(opline->op2)) - (actual - Z_STRVAL_P(EX_CONSTANT(opline->op2)))); + actual, Z_STRLEN_P(RT_CONSTANT(opline, opline->op2)) - (actual - Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)))); } /* non-qualified constant - allow text substitution */ zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)", Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var))); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } } else { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), c); } -#ifdef ZTS - if (c->flags & CONST_PERSISTENT) { - ZVAL_DUP(EX_VAR(opline->result.var), &c->value); - } else { - ZVAL_COPY(EX_VAR(opline->result.var), &c->value); - } -#else - ZVAL_COPY(EX_VAR(opline->result.var), &c->value); -#endif + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); ZEND_VM_NEXT_OPCODE(); } @@ -5031,29 +5047,26 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO { zend_class_entry *ce, *scope; zend_class_constant *c; - zval *value; + zval *value, *zv; USE_OPLINE SAVE_OPLINE(); do { if (OP1_TYPE == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); -#ifdef ZTS - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); -#endif + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); break; - } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))))) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else { if (OP1_TYPE == IS_UNUSED) { @@ -5066,21 +5079,23 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); break; } } - if (EXPECTED((c = zend_hash_find_ptr(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { + zv = zend_hash_find_ex(&ce->constants_table, Z_STR_P(RT_CONSTANT(opline, opline->op2)), 1); + if (EXPECTED(zv != NULL)) { + c = Z_PTR_P(zv); scope = EX(func)->op_array.scope; if (!zend_verify_const_access(c, scope)) { - zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(ce->name), Z_STRVAL_P(EX_CONSTANT(opline->op2))); + zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(ce->name), Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } value = &c->value; - if (Z_CONSTANT_P(value)) { + if (Z_TYPE_P(value) == IS_CONSTANT_AST) { zval_update_constant_ex(value, c->ce); if (UNEXPECTED(EG(exception) != NULL)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -5088,26 +5103,18 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO } } if (OP1_TYPE == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), value); } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce, value); } } else { - zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } } while (0); -#ifdef ZTS - if (ce->type == ZEND_INTERNAL_CLASS) { - ZVAL_DUP(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } -#else - ZVAL_COPY(EX_VAR(opline->result.var), value); -#endif + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); ZEND_VM_NEXT_OPCODE(); } @@ -5130,20 +5137,16 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSE if (OP1_TYPE == IS_TMP_VAR) { /* pass */ } else if (OP1_TYPE == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else if (OP1_TYPE == IS_CV) { ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else /* if (OP1_TYPE == IS_VAR) */ { if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { zend_refcounted *ref = Z_COUNTED_P(expr_ptr); expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; efree_size(ref, sizeof(zend_reference)); @@ -5195,13 +5198,13 @@ ZEND_VM_C_LABEL(num_index): ZEND_VM_C_GOTO(str_index); } else { zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } FREE_OP2(); } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -5216,20 +5219,16 @@ ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT| array = EX_VAR(opline->result.var); if (OP1_TYPE != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - - if (OP1_TYPE != IS_UNUSED) { + ZVAL_ARR(array, zend_new_array(size)); /* Explicitly initialize array as not-packed if flag is set */ if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init(Z_ARRVAL_P(array), 0); } + ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ADD_ARRAY_ELEMENT); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ADD_ARRAY_ELEMENT); } ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE) @@ -5277,15 +5276,16 @@ ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE) if (opline->extended_value == IS_ARRAY) { if (Z_TYPE_P(expr) != IS_OBJECT) { - ZVAL_NEW_ARR(result); - zend_hash_init(Z_ARRVAL_P(result), 8, NULL, ZVAL_PTR_DTOR, 0); if (Z_TYPE_P(expr) != IS_NULL) { + ZVAL_ARR(result, zend_new_array(8)); expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr); if (OP1_TYPE == IS_CONST) { if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr); } else { if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); } + } else { + ZVAL_EMPTY_ARRAY(result); } } else { ZVAL_COPY_VALUE(result, expr); @@ -5392,7 +5392,7 @@ ZEND_VM_HANDLER(196, ZEND_UNSET_CV, CV, UNUSED) ZVAL_UNDEF(var); SAVE_OPLINE(); - if (!--GC_REFCOUNT(garbage)) { + if (!GC_DELREF(garbage)) { zval_dtor_func(garbage); } else { gc_check_possible_root(garbage); @@ -5407,7 +5407,8 @@ ZEND_VM_HANDLER(196, ZEND_UNSET_CV, CV, UNUSED) ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) { USE_OPLINE - zval tmp, *varname; + zval *varname; + zend_string *name, *tmp_name; HashTable *target_symbol_table; zend_free_op free_op1; @@ -5415,20 +5416,23 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); - ZVAL_UNDEF(&tmp); - if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + if (OP1_TYPE == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); } - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; + name = zval_get_tmp_string(varname, &tmp_name); } target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + zend_hash_del_ind(target_symbol_table, name); - if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (OP1_TYPE != IS_CONST) { + zend_tmp_string_release(tmp_name); } FREE_OP1(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -5437,7 +5441,8 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) ZEND_VM_HANDLER(179, ZEND_UNSET_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) { USE_OPLINE - zval tmp, *varname; + zval *varname; + zend_string *name, *tmp_name; zend_class_entry *ce; zend_free_op free_op1; @@ -5445,35 +5450,38 @@ ZEND_VM_HANDLER(179, ZEND_UNSET_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); - ZVAL_UNDEF(&tmp); - if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + if (OP1_TYPE == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); } - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; + name = zval_get_tmp_string(varname, &tmp_name); } if (OP2_TYPE == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (OP1_TYPE != IS_CONST) { + zend_tmp_string_release(tmp_name); } FREE_OP1(); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); } } else if (OP2_TYPE == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (OP1_TYPE != IS_CONST) { + zend_tmp_string_release(tmp_name); } FREE_OP1(); HANDLE_EXCEPTION(); @@ -5481,10 +5489,10 @@ ZEND_VM_HANDLER(179, ZEND_UNSET_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); + zend_std_unset_static_property(ce, name); - if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (OP1_TYPE != IS_CONST) { + zend_tmp_string_release(tmp_name); } FREE_OP1(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -5650,7 +5658,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR) if (Z_OBJ_P(array_ptr)->properties && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties)--; + GC_DELREF(Z_OBJ_P(array_ptr)->properties); } Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); } @@ -5755,7 +5763,9 @@ ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR) } Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0); - FREE_OP1_VAR_PTR(); + if (OP1_TYPE == IS_VAR) { + FREE_OP1_VAR_PTR(); + } ZEND_VM_NEXT_OPCODE(); } else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { if (!Z_OBJCE_P(array_ptr)->get_iterator) { @@ -5773,13 +5783,15 @@ ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR) if (Z_OBJ_P(array_ptr)->properties && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties)--; + GC_DELREF(Z_OBJ_P(array_ptr)->properties); } Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); } Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0); - FREE_OP1_VAR_PTR(); + if (OP1_TYPE == IS_VAR) { + FREE_OP1_VAR_PTR(); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { zend_class_entry *ce = Z_OBJCE_P(array_ptr); @@ -6012,7 +6024,7 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit): ZVAL_COPY_VALUE_EX(res, value, gc, value_type); if (EXPECTED((value_type & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0)) { - GC_REFCOUNT(gc)++; + GC_ADDREF(gc); } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -6181,7 +6193,7 @@ ZEND_VM_C_LABEL(fe_fetch_w_exit): zend_reference *ref; ref = Z_REF_P(value); - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); zval_ptr_dtor(variable_ptr); ZVAL_REF(variable_ptr, ref); } @@ -6223,22 +6235,23 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH| zval *value; int result; zend_free_op free_op1; - zval tmp, *varname; + zval *varname; + zend_string *name, *tmp_name; HashTable *target_symbol_table; SAVE_OPLINE(); varname = GET_OP1_ZVAL_PTR(BP_VAR_IS); - ZVAL_UNDEF(&tmp); - if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; + if (OP1_TYPE == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); } target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); + value = zend_hash_find_ex_ind(target_symbol_table, name, OP1_TYPE == IS_CONST); - if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (OP1_TYPE != IS_CONST) { + zend_tmp_string_release(tmp_name); } FREE_OP1(); @@ -6260,20 +6273,21 @@ ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLA zval *value; int result; zend_free_op free_op1; - zval tmp, *varname; + zval *varname; + zend_string *name, *tmp_name; zend_class_entry *ce; SAVE_OPLINE(); varname = GET_OP1_ZVAL_PTR(BP_VAR_IS); - ZVAL_UNDEF(&tmp); - if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; + if (OP1_TYPE == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); } if (OP2_TYPE == IS_CONST) { - if (OP1_TYPE == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + if (OP1_TYPE == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -6281,22 +6295,22 @@ ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLA } ZEND_VM_C_GOTO(is_static_prop_return); - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); } } else { if (OP2_TYPE == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (OP1_TYPE != IS_CONST) { + zend_tmp_string_release(tmp_name); } FREE_OP1(); ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -6306,9 +6320,9 @@ ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLA ce = Z_CE_P(EX_VAR(opline->op2.var)); } if (OP1_TYPE == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))) == ce)) { + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -6319,14 +6333,14 @@ ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLA } } - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + value = zend_std_get_static_property(ce, name, 1); if (OP1_TYPE == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); } - if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (OP1_TYPE != IS_CONST) { + zend_tmp_string_release(tmp_name); } FREE_OP1(); @@ -6372,7 +6386,7 @@ ZEND_VM_C_LABEL(isset_again): } } ZEND_VM_C_LABEL(str_index_prop): - value = zend_hash_find_ind(ht, str); + value = zend_hash_find_ex_ind(ht, str, OP2_TYPE == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); ZEND_VM_C_LABEL(num_index_prop): @@ -6561,9 +6575,9 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY) do { EG(error_reporting) = 0; if (!EG(error_reporting_ini_entry)) { - zend_ini_entry *p = zend_hash_find_ptr(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING)); - if (p) { - EG(error_reporting_ini_entry) = p; + zval *zv = zend_hash_find_ex(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING), 1); + if (zv) { + EG(error_reporting_ini_entry) = (zend_ini_entry *)Z_PTR_P(zv); } else { break; } @@ -6631,7 +6645,7 @@ ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, JMP_ADDR) } else if (OP1_TYPE == IS_VAR && ref) { zend_reference *r = Z_REF_P(ref); - if (UNEXPECTED(--GC_REFCOUNT(r) == 0)) { + if (UNEXPECTED(GC_DELREF(r) == 0)) { efree_size(r, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(result)) { Z_ADDREF_P(result); @@ -6672,7 +6686,7 @@ ZEND_VM_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR) } else if (OP1_TYPE == IS_VAR && ref) { zend_reference *r = Z_REF_P(ref); - if (UNEXPECTED(--GC_REFCOUNT(r) == 0)) { + if (UNEXPECTED(GC_DELREF(r) == 0)) { efree_size(r, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(result)) { Z_ADDREF_P(result); @@ -6786,8 +6800,8 @@ ZEND_VM_HANDLER(145, ZEND_DECLARE_INHERITED_CLASS_DELAYED, ANY, VAR) zval *zce, *orig_zce; SAVE_OPLINE(); - if ((zce = zend_hash_find(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1)))) == NULL || - ((orig_zce = zend_hash_find(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1)+1))) != NULL && + if ((zce = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1)) == NULL || + ((orig_zce = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)+1), 1)) != NULL && Z_CE_P(zce) != Z_CE_P(orig_zce))) { do_bind_inherited_class(&EX(func)->op_array, opline, EG(class_table), Z_CE_P(EX_VAR(opline->op2.var)), 0); } @@ -6796,13 +6810,15 @@ ZEND_VM_HANDLER(145, ZEND_DECLARE_INHERITED_CLASS_DELAYED, ANY, VAR) ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, ANY, ANY, JMP_ADDR) { + zval *zv; zend_class_entry *ce; USE_OPLINE SAVE_OPLINE(); - ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1))); + zv = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1); + ZEND_ASSERT(zv != NULL); + ce = Z_CE_P(zv); Z_CE_P(EX_VAR(opline->result.var)) = ce; - ZEND_ASSERT(ce != NULL); if (ce->ce_flags & ZEND_ACC_ANON_BOUND) { ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); @@ -6818,13 +6834,15 @@ ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, ANY, ANY, JMP_ADDR) ZEND_VM_HANDLER(172, ZEND_DECLARE_ANON_INHERITED_CLASS, ANY, VAR, JMP_ADDR) { + zval *zv; zend_class_entry *ce; USE_OPLINE SAVE_OPLINE(); - ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1))); + zv = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1); + ZEND_ASSERT(zv != NULL); + ce = Z_CE_P(zv); Z_CE_P(EX_VAR(opline->result.var)) = ce; - ZEND_ASSERT(ce != NULL); if (ce->ce_flags & ZEND_ACC_ANON_BOUND) { ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); @@ -6875,11 +6893,11 @@ ZEND_VM_C_LABEL(try_instanceof): zend_class_entry *ce; if (OP2_TYPE == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); if (EXPECTED(ce)) { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); } } } else if (OP2_TYPE == IS_UNUSED) { @@ -6930,13 +6948,13 @@ ZEND_VM_HANDLER(144, ZEND_ADD_INTERFACE, ANY, CONST) zend_class_entry *iface; SAVE_OPLINE(); - iface = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + iface = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); if (UNEXPECTED(iface == NULL)) { - iface = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_INTERFACE); + iface = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_INTERFACE); if (UNEXPECTED(iface == NULL)) { ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), iface); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), iface); } if (UNEXPECTED((iface->ce_flags & ZEND_ACC_INTERFACE) == 0)) { @@ -6954,10 +6972,10 @@ ZEND_VM_HANDLER(154, ZEND_ADD_TRAIT, ANY, ANY) zend_class_entry *trait; SAVE_OPLINE(); - trait = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + trait = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); if (UNEXPECTED(trait == NULL)) { - trait = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), - EX_CONSTANT(opline->op2) + 1, + trait = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), + RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_TRAIT); if (UNEXPECTED(trait == NULL)) { ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -6965,7 +6983,7 @@ ZEND_VM_HANDLER(154, ZEND_ADD_TRAIT, ANY, ANY) if (!(trait->ce_flags & ZEND_ACC_TRAIT)) { zend_error_noreturn(E_ERROR, "%s cannot use %s - it is not a trait", ZSTR_VAL(ce->name), ZSTR_VAL(trait->name)); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), trait); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), trait); } zend_do_implement_trait(ce, trait); @@ -7154,14 +7172,14 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST) ZVAL_COPY(&c.value, val); if (Z_OPT_CONSTANT(c.value)) { if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) { - zval_ptr_dtor(&c.value); + zval_ptr_dtor_nogc(&c.value); FREE_OP1(); FREE_OP2(); HANDLE_EXCEPTION(); } } - c.flags = CONST_CS; /* non persistent, case sensetive */ - c.name = zend_string_dup(Z_STR_P(name), 0); + c.flags = CONST_CS; /* non persistent, case sensitive */ + c.name = zend_string_copy(Z_STR_P(name)); c.module_number = PHP_USER_CONSTANT; if (zend_register_constant(&c) == FAILURE) { @@ -7179,7 +7197,7 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED) zval *object; zend_class_entry *called_scope; - zfunc = zend_hash_find(EG(function_table), Z_STR_P(EX_CONSTANT(opline->op1))); + zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1); ZEND_ASSERT(zfunc != NULL && Z_FUNC_P(zfunc)->type == ZEND_USER_FUNCTION); if (Z_TYPE(EX(This)) == IS_OBJECT) { @@ -7523,7 +7541,7 @@ ZEND_VM_HOT_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST) zval *varname; zval *value; zval *variable_ptr; - uint32_t idx; + uintptr_t idx; zend_reference *ref; ZEND_VM_REPEATABLE_OPCODE @@ -7531,32 +7549,31 @@ ZEND_VM_HOT_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST) varname = GET_OP2_ZVAL_PTR(BP_VAR_R); /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ - idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)) - 1; - if (EXPECTED(idx < EG(symbol_table).nNumUsed)) { - Bucket *p = EG(symbol_table).arData + idx; + idx = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)) - 1; + if (EXPECTED(idx < EG(symbol_table).nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)EG(symbol_table).arData + idx); if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && (EXPECTED(p->key == Z_STR_P(varname)) || (EXPECTED(p->h == ZSTR_H(Z_STR_P(varname))) && EXPECTED(p->key != NULL) && - EXPECTED(ZSTR_LEN(p->key) == Z_STRLEN_P(varname)) && - EXPECTED(memcmp(ZSTR_VAL(p->key), Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) { + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(varname)))))) { - value = &EG(symbol_table).arData[idx].val; + value = (zval*)p; /* value = &p->val; */ ZEND_VM_C_GOTO(check_indirect); } } - value = zend_hash_find(&EG(symbol_table), Z_STR_P(varname)); + value = zend_hash_find_ex(&EG(symbol_table), Z_STR_P(varname), 1); if (UNEXPECTED(value == NULL)) { value = zend_hash_add_new(&EG(symbol_table), Z_STR_P(varname), &EG(uninitialized_zval)); - idx = ((char*)value - (char*)EG(symbol_table).arData) / sizeof(Bucket); + idx = (char*)value - (char*)EG(symbol_table).arData; /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1)); + CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(idx + 1)); } else { - idx = ((char*)value - (char*)EG(symbol_table).arData) / sizeof(Bucket); + idx = (char*)value - (char*)EG(symbol_table).arData; /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1)); + CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(idx + 1)); ZEND_VM_C_LABEL(check_indirect): /* GLOBAL variable may be an INDIRECT pointer to CV */ if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { @@ -7569,21 +7586,21 @@ ZEND_VM_C_LABEL(check_indirect): if (UNEXPECTED(!Z_ISREF_P(value))) { ref = (zend_reference*)emalloc(sizeof(zend_reference)); - GC_REFCOUNT(ref) = 2; + GC_SET_REFCOUNT(ref, 2); GC_TYPE_INFO(ref) = IS_REFERENCE; ZVAL_COPY_VALUE(&ref->val, value); Z_REF_P(value) = ref; Z_TYPE_INFO_P(value) = IS_REFERENCE_EX; } else { ref = Z_REF_P(value); - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); } variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) { zend_refcounted *ref = Z_COUNTED_P(variable_ptr); - uint32_t refcnt = --GC_REFCOUNT(ref); + uint32_t refcnt = GC_DELREF(ref); if (EXPECTED(variable_ptr != value)) { if (refcnt == 0) { @@ -7653,33 +7670,44 @@ ZEND_VM_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMP|VAR|CV, ANY, TYPE) +ZEND_VM_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMP|VAR|CV, ANY, TYPE_MASK) { USE_OPLINE zval *value; int result = 0; zend_free_op free_op1; - SAVE_OPLINE(); - value = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R); - if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) { - if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) { - const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value)); - - if (EXPECTED(type_name != NULL)) { - result = 1; - } - } else { + value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + if ((1 << (uint32_t)Z_TYPE_P(value) & opline->extended_value)) { +ZEND_VM_C_LABEL(type_check_resource): + if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE) + || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) { result = 1; } - } else if (UNEXPECTED(opline->extended_value == _IS_BOOL) && - EXPECTED(Z_TYPE_P(value) == IS_TRUE || Z_TYPE_P(value) == IS_FALSE)) { - result = 1; + } else if ((OP1_TYPE & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + if ((1 << (uint32_t)Z_TYPE_P(value) & opline->extended_value)) { + ZEND_VM_C_GOTO(type_check_resource); + } + } else if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + result = ((1 << IS_NULL) & opline->extended_value) != 0; + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(value, BP_VAR_R); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + FREE_OP1(); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); } - FREE_OP1(); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY) @@ -7688,12 +7716,12 @@ ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY) zend_constant *c; int result; - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))))) { + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { result = 1; - } else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op1), 0)) == NULL) { + } else if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0)) == NULL) { result = 0; } else { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), c); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), c); result = 1; } ZEND_VM_SMART_BRANCH(result, 0); @@ -7774,12 +7802,11 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY) SAVE_OPLINE(); - args = emalloc(sizeof(zend_array)); - zend_hash_init(args, num_args, NULL, ZVAL_PTR_DTOR, 0); if (num_args) { zval *p = ZEND_CALL_ARG(execute_data, 1); zval *end = p + num_args; + args = zend_new_array(num_args); zend_hash_real_init(args, 1); ZEND_HASH_FILL_PACKED(args) { do { @@ -7798,7 +7825,11 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY) ZEND_CALL_NUM_ARGS(call) = 2; ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name); - ZVAL_ARR(ZEND_CALL_ARG(call, 2), args); + if (num_args) { + ZVAL_ARR(ZEND_CALL_ARG(call, 2), args); + } else { + ZVAL_EMPTY_ARRAY(ZEND_CALL_ARG(call, 2)); + } zend_free_trampoline(fbc); fbc = call->func; @@ -7806,10 +7837,14 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY) if (UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } - i_init_func_execute_data(call, &fbc->op_array, ret); + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); if (EXPECTED(zend_execute_ex == execute_ex)) { - ZEND_VM_ENTER(); + LOAD_OPLINE(); + ZEND_VM_ENTER_EX(); } else { + execute_data = EX(prev_execute_data); + LOAD_OPLINE(); ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); zend_execute_ex(call); } @@ -7842,10 +7877,12 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY) } #if ZEND_DEBUG - ZEND_ASSERT( - EG(exception) || !call->func || - !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); + if (!EG(exception) && call->func) { + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); + } #endif EG(current_execute_data) = call->prev_execute_data; @@ -7928,16 +7965,16 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, CONST, REF) ZEND_ASSERT(ht != NULL); if (GC_REFCOUNT(ht) > 1) { if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_REFCOUNT(ht)--; + GC_DELREF(ht); } EX(func)->op_array.static_variables = ht = zend_array_dup(ht); } varname = GET_OP2_ZVAL_PTR(BP_VAR_R); - value = zend_hash_find(ht, Z_STR_P(varname)); + value = zend_hash_find_ex(ht, Z_STR_P(varname), 1); if (opline->extended_value) { - if (Z_CONSTANT_P(value)) { + if (Z_TYPE_P(value) == IS_CONSTANT_AST) { SAVE_OPLINE(); if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) { ZVAL_NULL(variable_ptr); @@ -7946,7 +7983,7 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, CONST, REF) } if (UNEXPECTED(!Z_ISREF_P(value))) { zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference)); - GC_REFCOUNT(ref) = 2; + GC_SET_REFCOUNT(ref, 2); GC_TYPE_INFO(ref) = IS_REFERENCE; ZVAL_COPY_VALUE(&ref->val, value); Z_REF_P(value) = ref; @@ -8022,7 +8059,7 @@ ZEND_VM_HANDLER(51, ZEND_MAKE_REF, VAR|CV, UNUSED) if (EXPECTED(!Z_ISREF_P(op1))) { ZVAL_MAKE_REF(op1); } - GC_REFCOUNT(Z_REF_P(op1))++; + GC_ADDREF(Z_REF_P(op1)); ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); } else { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), op1); @@ -8070,14 +8107,19 @@ ZEND_VM_HANDLER(188, ZEND_SWITCH_STRING, CONST|TMPVAR|CV, CONST, JMP_ADDR) jumptable = Z_ARRVAL_P(GET_OP2_ZVAL_PTR(BP_VAR_R)); if (Z_TYPE_P(op) != IS_STRING) { - ZVAL_DEREF(op); - if (Z_TYPE_P(op) != IS_STRING) { + if (OP1_TYPE == IS_CONST) { /* Wrong type, fall back to ZEND_CASE chain */ ZEND_VM_NEXT_OPCODE(); + } else { + ZVAL_DEREF(op); + if (Z_TYPE_P(op) != IS_STRING) { + /* Wrong type, fall back to ZEND_CASE chain */ + ZEND_VM_NEXT_OPCODE(); + } } } - jump_zv = zend_hash_find(jumptable, Z_STR_P(op)); + jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), OP1_TYPE == IS_CONST); if (jump_zv != NULL) { ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); ZEND_VM_CONTINUE(); @@ -8093,7 +8135,7 @@ ZEND_VM_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|VAR|CV, CONST, NUM) USE_OPLINE zend_free_op free_op1; zval *op1; - HashTable *ht = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); + HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); int result; SAVE_OPLINE(); @@ -8259,7 +8301,7 @@ ZEND_VM_HANDLER(195, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED) arg_count = EX_NUM_ARGS(); if (OP1_TYPE == IS_CONST) { - skip = Z_LVAL_P(EX_CONSTANT(opline->op1)); + skip = Z_LVAL_P(RT_CONSTANT(opline, opline->op1)); if (arg_count < skip) { result_size = 0; } else { @@ -8270,12 +8312,11 @@ ZEND_VM_HANDLER(195, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED) result_size = arg_count; } - ht = (zend_array *) emalloc(sizeof(zend_array)); - zend_hash_init(ht, result_size, NULL, ZVAL_PTR_DTOR, 0); - ZVAL_ARR(EX_VAR(opline->result.var), ht); - if (result_size) { uint32_t first_extra_arg = EX(func)->op_array.num_args; + + ht = zend_new_array(result_size); + ZVAL_ARR(EX_VAR(opline->result.var), ht); zend_hash_real_init(ht, 1); ZEND_HASH_FILL_PACKED(ht) { zval *p, *q; @@ -8319,6 +8360,8 @@ ZEND_VM_HANDLER(195, ZEND_FUNC_GET_ARGS, UNUSED|CONST, UNUSED) } } ZEND_HASH_FILL_END(); ht->nNumOfElements = result_size; + } else { + ZVAL_EMPTY_ARRAY(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index d1ea87bf68..b729a31906 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -314,15 +314,18 @@ static zend_uchar zend_user_opcodes[256] = {0, #define SPEC_RULE_QUICK_ARG 0x00100000 #define SPEC_RULE_SMART_BRANCH 0x00200000 #define SPEC_RULE_DIM_OBJ 0x00400000 +#define SPEC_RULE_COMMUTATIVE 0x00800000 static const uint32_t *zend_spec_handlers; -static const void **zend_opcode_handlers; +static const void * const *zend_opcode_handlers; static int zend_handlers_count; #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) -static const void **zend_opcode_handler_funcs; +static const void * const * zend_opcode_handler_funcs; static zend_op hybrid_halt_op; #endif +#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op); +#endif #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) static const void *zend_vm_get_opcode_handler_func(zend_uchar opcode, const zend_op* op); @@ -400,12 +403,15 @@ typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_H #define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE() #define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE() #if defined(ZEND_VM_FP_GLOBAL_REG) -# define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE() +# define ZEND_VM_ENTER_EX() ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE() +# define ZEND_VM_ENTER() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_ENTER_EX() # define ZEND_VM_LEAVE() ZEND_VM_CONTINUE() #elif defined(ZEND_VM_IP_GLOBAL_REG) -# define ZEND_VM_ENTER() opline = EG(current_execute_data)->opline; return 1 +# define ZEND_VM_ENTER_EX() return 1 +# define ZEND_VM_ENTER() opline = EG(current_execute_data)->opline; ZEND_VM_ENTER_EX() # define ZEND_VM_LEAVE() return 2 #else +# define ZEND_VM_ENTER_EX() return 1 # define ZEND_VM_ENTER() return 1 # define ZEND_VM_LEAVE() return 2 #endif @@ -414,6 +420,8 @@ typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_H #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)); static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS); +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS); + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -444,7 +452,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ #else if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { #endif - GC_REFCOUNT(object)--; + GC_DELREF(object); zend_object_store_ctor_failed(object); } OBJ_RELEASE(object); @@ -475,7 +483,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ #else if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { #endif - GC_REFCOUNT(object)--; + GC_DELREF(object); zend_object_store_ctor_failed(object); } OBJ_RELEASE(object); @@ -573,11 +581,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV fbc->internal_function.handler(call, ret); #if ZEND_DEBUG - ZEND_ASSERT( - EG(exception) || !call->func || - !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); - ZEND_ASSERT(!Z_ISREF_P(ret)); + if (!EG(exception) && call->func) { + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); + } #endif EG(current_execute_data) = execute_data; @@ -617,11 +626,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV fbc->internal_function.handler(call, ret); #if ZEND_DEBUG - ZEND_ASSERT( - EG(exception) || !call->func || - !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); - ZEND_ASSERT(!Z_ISREF_P(ret)); + if (!EG(exception) && call->func) { + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); + } #endif EG(current_execute_data) = execute_data; @@ -658,9 +668,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETV } call->prev_execute_data = execute_data; - i_init_func_execute_data(call, &fbc->op_array, ret); + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + LOAD_OPLINE(); - ZEND_VM_ENTER(); + ZEND_VM_ENTER_EX(); } static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -680,9 +692,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETV } call->prev_execute_data = execute_data; - i_init_func_execute_data(call, &fbc->op_array, ret); + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + LOAD_OPLINE(); - ZEND_VM_ENTER(); + ZEND_VM_ENTER_EX(); } static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -703,9 +717,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S } call->prev_execute_data = execute_data; - i_init_func_execute_data(call, &fbc->op_array, ret); + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + LOAD_OPLINE(); - ZEND_VM_ENTER(); + ZEND_VM_ENTER_EX(); } else { zval retval; ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); @@ -781,9 +797,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S } call->prev_execute_data = execute_data; - i_init_func_execute_data(call, &fbc->op_array, ret); + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + LOAD_OPLINE(); - ZEND_VM_ENTER(); + ZEND_VM_ENTER_EX(); } else { zval retval; ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); @@ -869,8 +887,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV } } - LOAD_OPLINE(); - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { ret = NULL; if (0) { @@ -879,11 +895,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV } call->prev_execute_data = execute_data; - i_init_func_execute_data(call, &fbc->op_array, ret); + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC); if (EXPECTED(zend_execute_ex == execute_ex)) { - ZEND_VM_ENTER(); + LOAD_OPLINE(); + ZEND_VM_ENTER_EX(); } else { + execute_data = EX(prev_execute_data); + LOAD_OPLINE(); ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); zend_execute_ex(call); } @@ -950,7 +970,7 @@ fcall_end: #else if (UNEXPECTED(EG(exception) != NULL) && (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR)) { #endif - GC_REFCOUNT(object)--; + GC_DELREF(object); zend_object_store_ctor_failed(object); } OBJ_RELEASE(object); @@ -994,8 +1014,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV } } - LOAD_OPLINE(); - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { ret = NULL; if (1) { @@ -1004,11 +1022,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV } call->prev_execute_data = execute_data; - i_init_func_execute_data(call, &fbc->op_array, ret); + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC); if (EXPECTED(zend_execute_ex == execute_ex)) { - ZEND_VM_ENTER(); + LOAD_OPLINE(); + ZEND_VM_ENTER_EX(); } else { + execute_data = EX(prev_execute_data); + LOAD_OPLINE(); ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); zend_execute_ex(call); } @@ -1075,7 +1097,7 @@ fcall_end: #else if (UNEXPECTED(EG(exception) != NULL) && (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR)) { #endif - GC_REFCOUNT(object)--; + GC_DELREF(object); zend_object_store_ctor_failed(object); } OBJ_RELEASE(object); @@ -1294,7 +1316,7 @@ send_again: if (Z_ISREF_P(arg)) { ZVAL_DUP(arg, Z_REFVAL_P(arg)); } else { - if (Z_REFCOUNTED_P(arg)) Z_ADDREF_P(arg); + Z_TRY_ADDREF_P(arg); } zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1); @@ -1499,7 +1521,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEN } } ZEND_HASH_FILL_END(); } else { - array_init(params); + ZVAL_EMPTY_ARRAY(params); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -1515,9 +1537,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEN do { EG(error_reporting) = 0; if (!EG(error_reporting_ini_entry)) { - zend_ini_entry *p = zend_hash_find_ptr(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING)); - if (p) { - EG(error_reporting_ini_entry) = p; + zval *zv = zend_hash_find_ex(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING), 1); + if (zv) { + EG(error_reporting_ini_entry) = (zend_ini_entry *)Z_PTR_P(zv); } else { break; } @@ -1585,13 +1607,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_SPEC_HANDLER(ZEN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zval *zv; zend_class_entry *ce; USE_OPLINE SAVE_OPLINE(); - ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1))); + zv = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1); + ZEND_ASSERT(zv != NULL); + ce = Z_CE_P(zv); Z_CE_P(EX_VAR(opline->result.var)) = ce; - ZEND_ASSERT(ce != NULL); if (ce->ce_flags & ZEND_ACC_ANON_BOUND) { ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); @@ -1650,10 +1674,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_TRAIT_SPEC_HANDLER(ZEND_OP zend_class_entry *trait; SAVE_OPLINE(); - trait = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + trait = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); if (UNEXPECTED(trait == NULL)) { - trait = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), - EX_CONSTANT(opline->op2) + 1, + trait = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), + RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_TRAIT); if (UNEXPECTED(trait == NULL)) { ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -1661,7 +1685,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_TRAIT_SPEC_HANDLER(ZEND_OP if (!(trait->ce_flags & ZEND_ACC_TRAIT)) { zend_error_noreturn(E_ERROR, "%s cannot use %s - it is not a trait", ZSTR_VAL(ce->name), ZSTR_VAL(trait->name)); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), trait); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), trait); } zend_do_implement_trait(ce, trait); @@ -1965,12 +1989,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z SAVE_OPLINE(); - args = emalloc(sizeof(zend_array)); - zend_hash_init(args, num_args, NULL, ZVAL_PTR_DTOR, 0); if (num_args) { zval *p = ZEND_CALL_ARG(execute_data, 1); zval *end = p + num_args; + args = zend_new_array(num_args); zend_hash_real_init(args, 1); ZEND_HASH_FILL_PACKED(args) { do { @@ -1989,7 +2012,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z ZEND_CALL_NUM_ARGS(call) = 2; ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name); - ZVAL_ARR(ZEND_CALL_ARG(call, 2), args); + if (num_args) { + ZVAL_ARR(ZEND_CALL_ARG(call, 2), args); + } else { + ZVAL_EMPTY_ARRAY(ZEND_CALL_ARG(call, 2)); + } zend_free_trampoline(fbc); fbc = call->func; @@ -1997,10 +2024,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z if (UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } - i_init_func_execute_data(call, &fbc->op_array, ret); + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); if (EXPECTED(zend_execute_ex == execute_ex)) { - ZEND_VM_ENTER(); + LOAD_OPLINE(); + ZEND_VM_ENTER_EX(); } else { + execute_data = EX(prev_execute_data); + LOAD_OPLINE(); ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); zend_execute_ex(call); } @@ -2033,10 +2064,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z } #if ZEND_DEBUG - ZEND_ASSERT( - EG(exception) || !call->func || - !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); + if (!EG(exception) && call->func) { + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); + } #endif EG(current_execute_data) = call->prev_execute_data; @@ -2094,14 +2127,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - zval *class_name = EX_CONSTANT(opline->op2); + zval *class_name = RT_CONSTANT(opline, opline->op2); try_class_name: if (IS_CONST == IS_CONST) { zend_class_entry *ce = CACHED_PTR(Z_CACHE_SLOT_P(class_name)); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(class_name), EX_CONSTANT(opline->op2) + 1, opline->extended_value); + ce = zend_fetch_class_by_name(Z_STR_P(class_name), RT_CONSTANT(opline, opline->op2) + 1, opline->extended_value); CACHE_PTR(Z_CACHE_SLOT_P(class_name), ce); } Z_CE_P(EX_VAR(opline->result.var)) = ce; @@ -2133,10 +2166,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME zval *function_name, *func; zend_execute_data *call; - function_name = (zval*)EX_CONSTANT(opline->op2); + function_name = (zval*)RT_CONSTANT(opline, opline->op2); fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name)); if (UNEXPECTED(fbc == NULL)) { - func = zend_hash_find(EG(function_table), Z_STR_P(function_name+1)); + func = zend_hash_find_ex(EG(function_table), Z_STR_P(function_name+1), 1); if (UNEXPECTED(func == NULL)) { SAVE_OPLINE(); zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(function_name)); @@ -2164,7 +2197,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_H zend_execute_data *call; SAVE_OPLINE(); - function_name = EX_CONSTANT(opline->op2); + function_name = RT_CONSTANT(opline, opline->op2); try_function_name: if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { @@ -2220,21 +2253,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CON zend_function *fbc; zend_execute_data *call; - func_name = EX_CONSTANT(opline->op2) + 1; - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + func_name = RT_CONSTANT(opline, opline->op2) + 1; + fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); if (UNEXPECTED(fbc == NULL)) { - func = zend_hash_find(EG(function_table), Z_STR_P(func_name)); + func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name), 1); if (func == NULL) { func_name++; - func = zend_hash_find(EG(function_table), Z_STR_P(func_name)); + func = zend_hash_find_ex(EG(function_table), Z_STR_P(func_name), 1); if (UNEXPECTED(func == NULL)) { SAVE_OPLINE(); - zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); HANDLE_EXCEPTION(); } } fbc = Z_FUNC_P(func); - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), fbc); if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } @@ -2252,14 +2285,14 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_SPEC_CO { USE_OPLINE - zval *fname = EX_CONSTANT(opline->op2); + zval *fname = RT_CONSTANT(opline, opline->op2); zval *func; zend_function *fbc; zend_execute_data *call; fbc = CACHED_PTR(Z_CACHE_SLOT_P(fname)); if (UNEXPECTED(fbc == NULL)) { - func = zend_hash_find(EG(function_table), Z_STR_P(fname)); + func = zend_hash_find_ex(EG(function_table), Z_STR_P(fname), 1); if (UNEXPECTED(func == NULL)) { SAVE_OPLINE(); zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(fname)); @@ -2292,11 +2325,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CON arg_num = opline->op1.num; param = _get_zval_ptr_cv_undef_BP_VAR_W(opline->result.var EXECUTE_DATA_CC); if (arg_num > EX_NUM_ARGS()) { - ZVAL_COPY(param, EX_CONSTANT(opline->op2)); - if (Z_OPT_CONSTANT_P(param)) { + ZVAL_COPY(param, RT_CONSTANT(opline, opline->op2)); + if (Z_OPT_TYPE_P(param) == IS_CONSTANT_AST) { SAVE_OPLINE(); if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) { - zval_ptr_dtor(param); + zval_ptr_dtor_nogc(param); ZVAL_UNDEF(param); HANDLE_EXCEPTION(); } @@ -2304,7 +2337,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CON } if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { - zval *default_value = EX_CONSTANT(opline->op2); + zval *default_value = RT_CONSTANT(opline, opline->op2); SAVE_OPLINE(); if (UNEXPECTED(!zend_verify_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(Z_CACHE_SLOT_P(default_value))) || EG(exception))) { @@ -2323,13 +2356,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_INTERFACE_SPEC_CONST_HANDL zend_class_entry *iface; SAVE_OPLINE(); - iface = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + iface = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); if (UNEXPECTED(iface == NULL)) { - iface = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_INTERFACE); + iface = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_INTERFACE); if (UNEXPECTED(iface == NULL)) { ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), iface); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), iface); } if (UNEXPECTED((iface->ce_flags & ZEND_ACC_INTERFACE) == 0)) { @@ -2340,6 +2373,106 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_INTERFACE_SPEC_CONST_HANDL ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->extended_value); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + zend_free_op free_op2; + zval *class_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + +try_class_name: + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + zend_class_entry *ce = CACHED_PTR(Z_CACHE_SLOT_P(class_name)); + + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(class_name), RT_CONSTANT(opline, opline->op2) + 1, opline->extended_value); + CACHE_PTR(Z_CACHE_SLOT_P(class_name), ce); + } + Z_CE_P(EX_VAR(opline->result.var)) = ce; + } else if (Z_TYPE_P(class_name) == IS_OBJECT) { + Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); + } else if (Z_TYPE_P(class_name) == IS_STRING) { + Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->extended_value); + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) { + class_name = Z_REFVAL_P(class_name); + goto try_class_name; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(class_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Class name must be a valid object or a string"); + } + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *function_name; + zend_execute_data *call; + + SAVE_OPLINE(); + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + +try_function_name: + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + call = zend_init_dynamic_call_string(Z_STR_P(function_name), opline->extended_value); + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) { + call = zend_init_dynamic_call_object(function_name, opline->extended_value); + } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY)) { + call = zend_init_dynamic_call_array(Z_ARRVAL_P(function_name), opline->extended_value); + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) { + function_name = Z_REFVAL_P(function_name); + goto try_function_name; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Function name must be a string"); + call = NULL; + } + + if (UNEXPECTED(!call)) { + HANDLE_EXCEPTION(); + } + + zval_ptr_dtor_nogc(free_op2); + if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) { + if (UNEXPECTED(EG(exception))) { + if (call) { + if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { + zend_string_release(call->func->common.function_name); + zend_free_trampoline(call->func); + } + zend_vm_stack_free_call_frame(call); + } + HANDLE_EXCEPTION(); + } + } else if (UNEXPECTED(!call)) { + HANDLE_EXCEPTION(); + } + + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_INHERITED_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -2355,8 +2488,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_INHERITED_CLASS_DELAYE zval *zce, *orig_zce; SAVE_OPLINE(); - if ((zce = zend_hash_find(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1)))) == NULL || - ((orig_zce = zend_hash_find(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1)+1))) != NULL && + if ((zce = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1)) == NULL || + ((orig_zce = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)+1), 1)) != NULL && Z_CE_P(zce) != Z_CE_P(orig_zce))) { do_bind_inherited_class(&EX(func)->op_array, opline, EG(class_table), Z_CE_P(EX_VAR(opline->op2.var)), 0); } @@ -2365,13 +2498,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_INHERITED_CLASS_DELAYE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zval *zv; zend_class_entry *ce; USE_OPLINE SAVE_OPLINE(); - ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1))); + zv = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1); + ZEND_ASSERT(zv != NULL); + ce = Z_CE_P(zv); Z_CE_P(EX_VAR(opline->result.var)) = ce; - ZEND_ASSERT(ce != NULL); if (ce->ce_flags & ZEND_ACC_ANON_BOUND) { ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); @@ -2400,7 +2535,7 @@ try_class_name: zend_class_entry *ce = CACHED_PTR(Z_CACHE_SLOT_P(class_name)); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(class_name), EX_CONSTANT(opline->op2) + 1, opline->extended_value); + ce = zend_fetch_class_by_name(Z_STR_P(class_name), RT_CONSTANT(opline, opline->op2) + 1, opline->extended_value); CACHE_PTR(Z_CACHE_SLOT_P(class_name), ce); } Z_CE_P(EX_VAR(opline->result.var)) = ce; @@ -2442,7 +2577,7 @@ try_class_name: zend_class_entry *ce = CACHED_PTR(Z_CACHE_SLOT_P(class_name)); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(class_name), EX_CONSTANT(opline->op2) + 1, opline->extended_value); + ce = zend_fetch_class_by_name(Z_STR_P(class_name), RT_CONSTANT(opline, opline->op2) + 1, opline->extended_value); CACHE_PTR(Z_CACHE_SLOT_P(class_name), ce); } Z_CE_P(EX_VAR(opline->result.var)) = ce; @@ -2523,113 +2658,13 @@ try_function_name: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->extended_value); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - zend_free_op free_op2; - zval *class_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - -try_class_name: - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_class_entry *ce = CACHED_PTR(Z_CACHE_SLOT_P(class_name)); - - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(class_name), EX_CONSTANT(opline->op2) + 1, opline->extended_value); - CACHE_PTR(Z_CACHE_SLOT_P(class_name), ce); - } - Z_CE_P(EX_VAR(opline->result.var)) = ce; - } else if (Z_TYPE_P(class_name) == IS_OBJECT) { - Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); - } else if (Z_TYPE_P(class_name) == IS_STRING) { - Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->extended_value); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) { - class_name = Z_REFVAL_P(class_name); - goto try_class_name; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(class_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Class name must be a valid object or a string"); - } - - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *function_name; - zend_execute_data *call; - - SAVE_OPLINE(); - function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - -try_function_name: - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - call = zend_init_dynamic_call_string(Z_STR_P(function_name), opline->extended_value); - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) { - call = zend_init_dynamic_call_object(function_name, opline->extended_value); - } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY)) { - call = zend_init_dynamic_call_array(Z_ARRVAL_P(function_name), opline->extended_value); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) { - function_name = Z_REFVAL_P(function_name); - goto try_function_name; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Function name must be a string"); - call = NULL; - } - - if (UNEXPECTED(!call)) { - HANDLE_EXCEPTION(); - } - - zval_ptr_dtor_nogc(free_op2); - if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) { - if (UNEXPECTED(EG(exception))) { - if (call) { - if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { - zend_string_release(call->func->common.function_name); - zend_free_trampoline(call->func); - } - zend_vm_stack_free_call_frame(call); - } - HANDLE_EXCEPTION(); - } - } else if (UNEXPECTED(!call)) { - HANDLE_EXCEPTION(); - } - - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1; - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1)); ZEND_VM_NEXT_OPCODE(); @@ -2637,7 +2672,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_CONST_HANDLER(ZEND SAVE_OPLINE(); bitwise_not_function(EX_VAR(opline->result.var), - EX_CONSTANT(opline->op1)); + RT_CONSTANT(opline, opline->op1)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -2648,7 +2683,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CONST_HANDLER(ZE zval *val; - val = EX_CONSTANT(opline->op1); + val = RT_CONSTANT(opline, opline->op1); if (Z_TYPE_INFO_P(val) == IS_TRUE) { ZVAL_FALSE(EX_VAR(opline->result.var)); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { @@ -2674,7 +2709,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_O zval *z; SAVE_OPLINE(); - z = EX_CONSTANT(opline->op1); + z = RT_CONSTANT(opline, opline->op1); if (Z_TYPE_P(z) == IS_STRING) { zend_string *str = Z_STR_P(z); @@ -2683,7 +2718,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_O zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); } } else { - zend_string *str = _zval_get_string_func(z); + zend_string *str = zval_get_string_func(z); if (ZSTR_LEN(str) != 0) { zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); @@ -2702,7 +2737,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_CONST_HA zval *val; - val = EX_CONSTANT(opline->op1); + val = RT_CONSTANT(opline, opline->op1); if (Z_TYPE_INFO_P(val) == IS_TRUE) { ZEND_VM_SET_NEXT_OPCODE(opline + 1); @@ -2734,7 +2769,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_CONST_H zval *val; - val = EX_CONSTANT(opline->op1); + val = RT_CONSTANT(opline, opline->op1); if (Z_TYPE_INFO_P(val) == IS_TRUE) { ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); @@ -2765,7 +2800,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CONST_ zval *val; - val = EX_CONSTANT(opline->op1); + val = RT_CONSTANT(opline, opline->op1); if (EXPECTED(Z_TYPE_INFO_P(val) == IS_TRUE)) { ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); @@ -2798,7 +2833,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CONST_HANDLER(ZEN zval *val; int ret; - val = EX_CONSTANT(opline->op1); + val = RT_CONSTANT(opline, opline->op1); if (Z_TYPE_INFO_P(val) == IS_TRUE) { ZVAL_TRUE(EX_VAR(opline->result.var)); @@ -2835,7 +2870,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CONST_HANDLER(ZE zval *val; int ret; - val = EX_CONSTANT(opline->op1); + val = RT_CONSTANT(opline, opline->op1); if (Z_TYPE_INFO_P(val) == IS_TRUE) { ZVAL_TRUE(EX_VAR(opline->result.var)); @@ -2872,7 +2907,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_ zval *return_value; zend_free_op free_op1; - retval_ptr = EX_CONSTANT(opline->op1); + retval_ptr = RT_CONSTANT(opline, opline->op1); return_value = EX(return_value); if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) { SAVE_OPLINE(); @@ -2917,7 +2952,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_ retval_ptr = Z_REFVAL_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { Z_ADDREF_P(retval_ptr); @@ -2944,7 +2979,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDL /* Not supposed to happen, but we'll allow it */ zend_error(E_NOTICE, "Only variable references should be returned by reference"); - retval_ptr = EX_CONSTANT(opline->op1); + retval_ptr = RT_CONSTANT(opline, opline->op1); if (!EX(return_value)) { } else { @@ -2955,7 +2990,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDL ZVAL_NEW_REF(EX(return_value), retval_ptr); if (IS_CONST == IS_CONST) { - if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr); + Z_TRY_ADDREF_P(retval_ptr); } } break; @@ -2996,7 +3031,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_CONST_HA zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); SAVE_OPLINE(); - retval = EX_CONSTANT(opline->op1); + retval = RT_CONSTANT(opline, opline->op1); /* Copy return value into generator->retval */ if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { @@ -3015,7 +3050,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_CONST_HA retval = Z_REFVAL_P(retval); ZVAL_COPY_VALUE(&generator->retval, retval); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(retval)) { Z_ADDREF_P(retval); @@ -3039,7 +3074,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_CONST_HANDLER(ZEND_ SAVE_OPLINE(); - value = EX_CONSTANT(opline->op1); + value = RT_CONSTANT(opline, opline->op1); do { if (IS_CONST == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) { @@ -3063,7 +3098,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_CONST_HANDLER(ZEND_ zend_exception_save(); if (IS_CONST != IS_TMP_VAR) { - if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value); + Z_TRY_ADDREF_P(value); } zend_throw_exception_object(value); @@ -3078,7 +3113,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONS zval *value, *arg; - value = EX_CONSTANT(opline->op1); + value = RT_CONSTANT(opline, opline->op1); arg = ZEND_CALL_VAR(EX(call), opline->result.var); ZVAL_COPY_VALUE(arg, value); if (IS_CONST == IS_CONST) { @@ -3109,7 +3144,7 @@ send_val_by_ref: ZVAL_UNDEF(arg); HANDLE_EXCEPTION(); } - value = EX_CONSTANT(opline->op1); + value = RT_CONSTANT(opline, opline->op1); arg = ZEND_CALL_VAR(EX(call), opline->result.var); ZVAL_COPY_VALUE(arg, value); if (IS_CONST == IS_CONST) { @@ -3140,7 +3175,7 @@ send_val_by_ref: ZVAL_UNDEF(arg); HANDLE_EXCEPTION(); } - value = EX_CONSTANT(opline->op1); + value = RT_CONSTANT(opline, opline->op1); arg = ZEND_CALL_VAR(EX(call), opline->result.var); ZVAL_COPY_VALUE(arg, value); if (IS_CONST == IS_CONST) { @@ -3158,7 +3193,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_CONST_HANDLER(Z SAVE_OPLINE(); - arg = EX_CONSTANT(opline->op1); + arg = RT_CONSTANT(opline, opline->op1); param = ZEND_CALL_VAR(EX(call), opline->result.var); if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) { @@ -3180,7 +3215,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_O zval *val; - val = EX_CONSTANT(opline->op1); + val = RT_CONSTANT(opline, opline->op1); if (Z_TYPE_INFO_P(val) == IS_TRUE) { ZVAL_TRUE(EX_VAR(opline->result.var)); } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { @@ -3209,15 +3244,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OP SAVE_OPLINE(); if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -3281,7 +3316,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_ zend_object_clone_obj_t clone_call; SAVE_OPLINE(); - obj = EX_CONSTANT(opline->op1); + obj = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -3356,7 +3391,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_HANDLER(ZEND_O zval *result = EX_VAR(opline->result.var); SAVE_OPLINE(); - expr = EX_CONSTANT(opline->op1); + expr = RT_CONSTANT(opline, opline->op1); switch (opline->extended_value) { case IS_NULL: @@ -3392,15 +3427,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_HANDLER(ZEND_O if (opline->extended_value == IS_ARRAY) { if (Z_TYPE_P(expr) != IS_OBJECT) { - ZVAL_NEW_ARR(result); - zend_hash_init(Z_ARRVAL_P(result), 8, NULL, ZVAL_PTR_DTOR, 0); if (Z_TYPE_P(expr) != IS_NULL) { + ZVAL_ARR(result, zend_new_array(8)); expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr); if (IS_CONST == IS_CONST) { if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr); } else { if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); } + } else { + ZVAL_EMPTY_ARRAY(result); } } else { ZVAL_COPY_VALUE(result, expr); @@ -3436,7 +3472,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN zval *inc_filename; SAVE_OPLINE(); - inc_filename = EX_CONSTANT(opline->op1); + inc_filename = RT_CONSTANT(opline, opline->op1); new_op_array = zend_include_or_eval(inc_filename, opline->extended_value); if (UNEXPECTED(EG(exception) != NULL)) { @@ -3504,7 +3540,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER( SAVE_OPLINE(); - array_ptr = EX_CONSTANT(opline->op1); + array_ptr = RT_CONSTANT(opline, opline->op1); if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { result = EX_VAR(opline->result.var); ZVAL_COPY_VALUE(result, array_ptr); @@ -3524,7 +3560,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER( if (Z_OBJ_P(array_ptr)->properties && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties)--; + GC_DELREF(Z_OBJ_P(array_ptr)->properties); } Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); } @@ -3604,7 +3640,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CONST_HANDLER array_ptr = Z_REFVAL_P(array_ref); } } else { - array_ref = array_ptr = EX_CONSTANT(opline->op1); + array_ref = array_ptr = RT_CONSTANT(opline, opline->op1); } if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { @@ -3627,6 +3663,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CONST_HANDLER } Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0); + if (IS_CONST == IS_VAR) { + + } ZEND_VM_NEXT_OPCODE(); } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { if (!Z_OBJCE_P(array_ptr)->get_iterator) { @@ -3644,12 +3683,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CONST_HANDLER if (Z_OBJ_P(array_ptr)->properties && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties)--; + GC_DELREF(Z_OBJ_P(array_ptr)->properties); } Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); } Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0); + if (IS_CONST == IS_VAR) { + + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { zend_class_entry *ce = Z_OBJCE_P(array_ptr); @@ -3735,7 +3777,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_CONST_HANDLER(ZEND_O SAVE_OPLINE(); if (IS_CONST != IS_UNUSED) { - zval *ptr = EX_CONSTANT(opline->op1); + zval *ptr = RT_CONSTANT(opline, opline->op1); do { if (Z_TYPE_P(ptr) == IS_LONG) { @@ -3766,7 +3808,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_CONST_HANDLER(ZEN int ret; SAVE_OPLINE(); - value = EX_CONSTANT(opline->op1); + value = RT_CONSTANT(opline, opline->op1); if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(value)) { if (IS_CONST == IS_VAR) { @@ -3794,7 +3836,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_CONST_HANDLER(ZEN } else if (IS_CONST == IS_VAR && ref) { zend_reference *r = Z_REF_P(ref); - if (UNEXPECTED(--GC_REFCOUNT(r) == 0)) { + if (UNEXPECTED(GC_DELREF(r) == 0)) { efree_size(r, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(result)) { Z_ADDREF_P(result); @@ -3815,7 +3857,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CONST_HANDLER(ZE zval *ref = NULL; SAVE_OPLINE(); - value = EX_CONSTANT(opline->op1); + value = RT_CONSTANT(opline, opline->op1); if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(value)) { if (IS_CONST == IS_VAR) { @@ -3834,7 +3876,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CONST_HANDLER(ZE } else if (IS_CONST == IS_VAR && ref) { zend_reference *r = Z_REF_P(ref); - if (UNEXPECTED(--GC_REFCOUNT(r) == 0)) { + if (UNEXPECTED(GC_DELREF(r) == 0)) { efree_size(r, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(result)) { Z_ADDREF_P(result); @@ -3854,7 +3896,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CON zval *value; zval *result = EX_VAR(opline->result.var); - value = EX_CONSTANT(opline->op1); + value = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { SAVE_OPLINE(); GET_OP1_UNDEF_CV(value, BP_VAR_R); @@ -3897,7 +3939,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CONST_HANDLER( SAVE_OPLINE(); - val = EX_CONSTANT(opline->op1); + val = RT_CONSTANT(opline, opline->op1); if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator"); @@ -3997,7 +4039,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CONST_HANDLER(ZEND zval *value; - value = EX_CONSTANT(opline->op1); + value = RT_CONSTANT(opline, opline->op1); if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); @@ -4047,26 +4089,37 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CONST_HANDLER( int result = 0; - SAVE_OPLINE(); - value = EX_CONSTANT(opline->op1); - if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) { - if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) { - const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value)); - - if (EXPECTED(type_name != NULL)) { - result = 1; - } - } else { + value = RT_CONSTANT(opline, opline->op1); + if ((1 << (uint32_t)Z_TYPE_P(value) & opline->extended_value)) { +type_check_resource: + if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE) + || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) { result = 1; } - } else if (UNEXPECTED(opline->extended_value == _IS_BOOL) && - EXPECTED(Z_TYPE_P(value) == IS_TRUE || Z_TYPE_P(value) == IS_FALSE)) { - result = 1; + } else if ((IS_CONST & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + if ((1 << (uint32_t)Z_TYPE_P(value) & opline->extended_value)) { + goto type_check_resource; + } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + result = ((1 << IS_NULL) & opline->extended_value) != 0; + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(value, BP_VAR_R); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); + } } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DEFINED_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -4075,12 +4128,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DEFINED_SPEC_CONST_HANDLER(ZEN zend_constant *c; int result; - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))))) { + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { result = 1; - } else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op1), 0)) == NULL) { + } else if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0)) == NULL) { result = 0; } else { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), c); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), c); result = 1; } ZEND_VM_SMART_BRANCH(result, 0); @@ -4094,7 +4147,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_DOUBLE_S zval *value; - value = EX_CONSTANT(opline->op1); + value = RT_CONSTANT(opline, opline->op1); ZVAL_DOUBLE(EX_VAR(opline->result.var), Z_DVAL_P(value)); ZEND_VM_NEXT_OPCODE(); } @@ -4105,7 +4158,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_NOREF_SP zval *value; - value = EX_CONSTANT(opline->op1); + value = RT_CONSTANT(opline, opline->op1); ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); ZEND_VM_NEXT_OPCODE(); } @@ -4116,8 +4169,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CONST_HANDLER(Z zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { result = EX_VAR(opline->result.var); @@ -4159,8 +4212,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_CONST_HANDLER(Z zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { result = EX_VAR(opline->result.var); @@ -4202,8 +4255,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CONST_CONST_HANDLER(Z zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { zend_long overflow; @@ -4249,8 +4302,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_CONST_HANDLER(Z zval *op1, *op2; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); fast_div_function(EX_VAR(opline->result.var), op1, op2); @@ -4263,8 +4316,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_CONST_HANDLER(Z zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { result = EX_VAR(opline->result.var); @@ -4302,8 +4355,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_CONST_HANDLER(ZE zval *op1, *op2; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { @@ -4330,8 +4383,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_CONST_HANDLER(ZE zval *op1, *op2; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { @@ -4359,8 +4412,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_CONST_HANDLER(Z zval *op1, *op2; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); pow_function(EX_VAR(opline->result.var), op1, op2); @@ -4373,8 +4426,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CONST_HANDLE zval *op1, *op2; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { @@ -4382,38 +4435,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CONST_HANDLE zend_string *op2_str = Z_STR_P(op2); zend_string *str; - do { - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - - break; - } - } - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - - break; - } + if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (IS_CONST != IS_CONST && IS_CONST != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; + } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - } while (0); + } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + } ZEND_VM_NEXT_OPCODE(); } else { SAVE_OPLINE(); @@ -4439,8 +4490,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_CONST_ int result; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); result = fast_is_identical_function(op1, op2); @@ -4457,8 +4508,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CO int result; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); result = fast_is_not_identical_function(op1, op2); @@ -4473,8 +4524,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_CONST_HAND zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); do { int result; @@ -4496,17 +4547,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_CONST_HAND } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); } else { @@ -4541,8 +4582,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_ zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); do { int result; @@ -4564,17 +4605,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_ } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 0; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 1; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0); - } + result = !zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); } else { @@ -4609,8 +4640,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_CONST_HA zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); do { int result; @@ -4659,8 +4690,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); do { int result; @@ -4710,8 +4741,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_CONST_HAN zval *op1, *op2; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); compare_function(EX_VAR(opline->result.var), op1, op2); @@ -4724,8 +4755,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_CONST_HANDLER zval *op1, *op2; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); @@ -4751,8 +4782,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_CONST_HANDLE zval *op1, *op2; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); @@ -4778,8 +4809,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_CONST_HANDLE zval *op1, *op2; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); @@ -4806,8 +4837,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_CONST_HAND zval *op1, *op2; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); boolean_xor_function(EX_VAR(opline->result.var), op1, op2); @@ -4822,9 +4853,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ zval *retval; SAVE_OPLINE(); - varname = EX_CONSTANT(opline->op1); + varname = RT_CONSTANT(opline, opline->op1); - retval = zend_fetch_static_property_address(varname, IS_CONST, opline->op2, IS_CONST, type EXECUTE_DATA_CC); + retval = zend_fetch_static_property_address(varname, IS_CONST, opline->op2, IS_CONST, type EXECUTE_DATA_CC OPLINE_CC); if (UNEXPECTED(retval == NULL)) { if (EG(exception)) { @@ -4888,8 +4919,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_H zval *container, *dim, *value, *result; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); - dim = EX_CONSTANT(opline->op2); + container = RT_CONSTANT(opline, opline->op1); + dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_array: @@ -4924,8 +4955,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_ zval *container; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); + container = RT_CONSTANT(opline, opline->op1); + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, RT_CONSTANT(opline, opline->op2), IS_CONST EXECUTE_DATA_CC); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -4934,40 +4965,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zend_free_op free_op1; - - SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = NULL; - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { if (IS_CONST == IS_UNUSED) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use [] for reading"); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = EX_CONSTANT(opline->op1); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); - - + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -4977,26 +4996,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_H zval *container; zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); + container = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = EX_CONSTANT(opline->op2); + offset = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CONST || (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_r_no_object; + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - } else { goto fetch_obj_r_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -5004,23 +5031,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_H zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (IS_CONST == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if (IS_CONST == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } } } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (UNEXPECTED(zobj->handlers->read_property == NULL)) { @@ -5031,7 +5082,7 @@ fetch_obj_r_no_object: zend_string_release(property_name); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); @@ -5050,26 +5101,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_ zval *container; zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); + container = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = EX_CONSTANT(opline->op2); + offset = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CONST || (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_is_no_object; + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } } - } else { goto fetch_obj_is_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -5077,21 +5130,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_ zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (IS_CONST == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if (IS_CONST == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } } } } @@ -5101,7 +5176,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -5116,48 +5191,33 @@ fetch_obj_is_no_object: static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1; - zval *property; - - SAVE_OPLINE(); - container = NULL; - - if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - property = EX_CONSTANT(opline->op2); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); - zend_fetch_dimension_address_read_LIST(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2) EXECUTE_DATA_CC); + container = RT_CONSTANT(opline, opline->op1); + zend_fetch_dimension_address_LIST_r(EX_VAR(opline->result.var), container, RT_CONSTANT(opline, opline->op2) EXECUTE_DATA_CC); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -5170,46 +5230,44 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CONST_H zend_string *op1_str, *op2_str, *str; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; - do { - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - - break; - } - } - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - - break; - } + if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (IS_CONST != IS_CONST && IS_CONST != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; + } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - } while (0); + } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + } ZEND_VM_NEXT_OPCODE(); } @@ -5222,7 +5280,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CONST_H if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - op1_str = _zval_get_string_func(op1); + op1_str = zval_get_string_func(op1); } if (IS_CONST == IS_CONST) { op2_str = Z_STR_P(op2); @@ -5232,13 +5290,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CONST_H if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { GET_OP2_UNDEF_CV(op2, BP_VAR_R); } - op2_str = _zval_get_string_func(op2); + op2_str = zval_get_string_func(op2); } do { if (IS_CONST != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { if (IS_CONST == IS_CONST) { - zend_string_addref(op2_str); + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } } ZVAL_STR(EX_VAR(opline->result.var), op2_str); zend_string_release(op1_str); @@ -5248,7 +5308,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CONST_H if (IS_CONST != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { if (IS_CONST == IS_CONST) { - zend_string_addref(op1_str); + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } } ZVAL_STR(EX_VAR(opline->result.var), op1_str); zend_string_release(op2_str); @@ -5285,13 +5347,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CO SAVE_OPLINE(); - object = EX_CONSTANT(opline->op1); + object = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = EX_CONSTANT(opline->op2); + function_name = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -5356,7 +5418,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CO } /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); @@ -5382,7 +5444,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CO } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(obj)++; /* For $this pointer */ + GC_ADDREF(obj); /* For $this pointer */ } @@ -5411,14 +5473,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -5433,16 +5495,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST == IS_CONST && IS_CONST == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { /* nothing to do */ } else if (IS_CONST != IS_CONST && IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); } else if (IS_CONST != IS_UNUSED) { - function_name = EX_CONSTANT(opline->op2); + function_name = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST) { if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { @@ -5467,7 +5529,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { @@ -5567,7 +5629,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; SAVE_OPLINE(); - function_name = EX_CONSTANT(opline->op2); + function_name = RT_CONSTANT(opline, opline->op2); if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { func = fcc.function_handler; called_scope = fcc.called_scope; @@ -5586,14 +5648,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS if (func->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT); - GC_REFCOUNT((zend_object*)func->common.prototype)++; + GC_ADDREF((zend_object*)func->common.prototype); call_info |= ZEND_CALL_CLOSURE; if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { call_info |= ZEND_CALL_FAKE_CLOSURE; } } else if (object) { call_info |= ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(object)++; /* For $this pointer */ + GC_ADDREF(object); /* For $this pointer */ } if ((IS_CONST & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { @@ -5610,7 +5672,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS init_func_run_time_cache(&func->op_array); } } else { - zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(EX_CONSTANT(opline->op1)), error); + zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); efree(error); if (UNEXPECTED(EG(exception))) { @@ -5635,8 +5697,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER( zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_CONSTANT(opline->op2); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); do { int result; @@ -5658,17 +5720,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER( } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); } else { break; @@ -5699,29 +5751,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS { zend_class_entry *ce, *scope; zend_class_constant *c; - zval *value; + zval *value, *zv; USE_OPLINE SAVE_OPLINE(); do { if (IS_CONST == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); -#ifdef ZTS - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); -#endif + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); break; - } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))))) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else { if (IS_CONST == IS_UNUSED) { @@ -5734,21 +5783,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); break; } } - if (EXPECTED((c = zend_hash_find_ptr(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { + zv = zend_hash_find_ex(&ce->constants_table, Z_STR_P(RT_CONSTANT(opline, opline->op2)), 1); + if (EXPECTED(zv != NULL)) { + c = Z_PTR_P(zv); scope = EX(func)->op_array.scope; if (!zend_verify_const_access(c, scope)) { - zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(ce->name), Z_STRVAL_P(EX_CONSTANT(opline->op2))); + zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(ce->name), Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } value = &c->value; - if (Z_CONSTANT_P(value)) { + if (Z_TYPE_P(value) == IS_CONSTANT_AST) { zval_update_constant_ex(value, c->ce); if (UNEXPECTED(EG(exception) != NULL)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -5756,26 +5807,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS } } if (IS_CONST == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), value); } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce, value); } } else { - zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } } while (0); -#ifdef ZTS - if (ce->type == ZEND_INTERNAL_CLASS) { - ZVAL_DUP(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } -#else - ZVAL_COPY(EX_VAR(opline->result.var), value); -#endif + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); ZEND_VM_NEXT_OPCODE(); } @@ -5794,24 +5837,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C Z_ADDREF_P(expr_ptr); } else { - expr_ptr = EX_CONSTANT(opline->op1); + expr_ptr = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_TMP_VAR) { /* pass */ } else if (IS_CONST == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else if (IS_CONST == IS_CV) { ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else /* if (IS_CONST == IS_VAR) */ { if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { zend_refcounted *ref = Z_COUNTED_P(expr_ptr); expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; efree_size(ref, sizeof(zend_reference)); @@ -5824,7 +5863,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C if (IS_CONST != IS_UNUSED) { - zval *offset = EX_CONSTANT(opline->op2); + zval *offset = RT_CONSTANT(opline, opline->op2); zend_string *str; zend_ulong hval; @@ -5863,13 +5902,13 @@ num_index: goto str_index; } else { zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -5884,62 +5923,62 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CONST_HA array = EX_VAR(opline->result.var); if (IS_CONST != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - - if (IS_CONST != IS_UNUSED) { + ZVAL_ARR(array, zend_new_array(size)); /* Explicitly initialize array as not-packed if flag is set */ if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init(Z_ARRVAL_P(array), 0); } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval tmp, *varname; + zval *varname; + zend_string *name, *tmp_name; zend_class_entry *ce; SAVE_OPLINE(); - varname = EX_CONSTANT(opline->op1); + varname = RT_CONSTANT(opline, opline->op1); - ZVAL_UNDEF(&tmp); - if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); } - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; + name = zval_get_tmp_string(varname, &tmp_name); } if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); } } else if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } HANDLE_EXCEPTION(); @@ -5947,10 +5986,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_C } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); + zend_std_unset_static_property(ce, name); - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -5962,20 +6001,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC zval *value; int result; - zval tmp, *varname; + zval *varname; + zend_string *name, *tmp_name; zend_class_entry *ce; SAVE_OPLINE(); - varname = EX_CONSTANT(opline->op1); - ZVAL_UNDEF(&tmp); - if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; + varname = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); } if (IS_CONST == IS_CONST) { - if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -5983,22 +6023,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); } } else { if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -6008,9 +6048,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC ce = Z_CE_P(EX_VAR(opline->op2.var)); } if (IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))) == ce)) { + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -6021,14 +6061,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } } - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + value = zend_std_get_static_property(ce, name, 1); if (IS_CONST == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); } - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } is_static_prop_return: @@ -6054,8 +6094,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON zval *offset; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); - offset = EX_CONSTANT(opline->op2); + container = RT_CONSTANT(opline, opline->op1); + offset = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; @@ -6073,7 +6113,7 @@ isset_again: } } str_index_prop: - value = zend_hash_find_ind(ht, str); + value = zend_hash_find_ex_ind(ht, str, IS_CONST == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: @@ -6185,13 +6225,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CO zval *offset; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); + container = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = EX_CONSTANT(opline->op2); + offset = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CONST || (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -6231,20 +6271,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST zend_constant c; SAVE_OPLINE(); - name = EX_CONSTANT(opline->op1); - val = EX_CONSTANT(opline->op2); + name = RT_CONSTANT(opline, opline->op1); + val = RT_CONSTANT(opline, opline->op2); ZVAL_COPY(&c.value, val); if (Z_OPT_CONSTANT(c.value)) { if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) { - zval_ptr_dtor(&c.value); + zval_ptr_dtor_nogc(&c.value); HANDLE_EXCEPTION(); } } - c.flags = CONST_CS; /* non persistent, case sensetive */ - c.name = zend_string_dup(Z_STR_P(name), 0); + c.flags = CONST_CS; /* non persistent, case sensitive */ + c.name = zend_string_copy(Z_STR_P(name)); c.module_number = PHP_USER_CONSTANT; if (zend_register_constant(&c) == FAILURE) { @@ -6287,7 +6327,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = EX_CONSTANT(opline->op1); + value = RT_CONSTANT(opline, opline->op1); ZVAL_COPY_VALUE(&generator->value, value); if (IS_CONST == IS_CONST) { if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { @@ -6311,7 +6351,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER } } else { - zval *value = EX_CONSTANT(opline->op1); + zval *value = RT_CONSTANT(opline, opline->op1); /* Consts, temporary variables and references need copying */ if (IS_CONST == IS_CONST) { @@ -6339,7 +6379,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER /* Set the new yielded key */ if (IS_CONST != IS_UNUSED) { - zval *key = EX_CONSTANT(opline->op2); + zval *key = RT_CONSTANT(opline, opline->op2); /* Consts, temporary variables and references need copying */ if (IS_CONST == IS_CONST) { @@ -6397,8 +6437,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_CONST_CONST_H zval *op, *jump_zv; HashTable *jumptable; - op = EX_CONSTANT(opline->op1); - jumptable = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); + op = RT_CONSTANT(opline, opline->op1); + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); if (Z_TYPE_P(op) != IS_LONG) { ZVAL_DEREF(op); @@ -6426,18 +6466,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPEC_CONST_CONST zval *op, *jump_zv; HashTable *jumptable; - op = EX_CONSTANT(opline->op1); - jumptable = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); + op = RT_CONSTANT(opline, opline->op1); + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); if (Z_TYPE_P(op) != IS_STRING) { - ZVAL_DEREF(op); - if (Z_TYPE_P(op) != IS_STRING) { + if (IS_CONST == IS_CONST) { /* Wrong type, fall back to ZEND_CASE chain */ ZEND_VM_NEXT_OPCODE(); + } else { + ZVAL_DEREF(op); + if (Z_TYPE_P(op) != IS_STRING) { + /* Wrong type, fall back to ZEND_CASE chain */ + ZEND_VM_NEXT_OPCODE(); + } } } - jump_zv = zend_hash_find(jumptable, Z_STR_P(op)); + jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), IS_CONST == IS_CONST); if (jump_zv != NULL) { ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); ZEND_VM_CONTINUE(); @@ -6453,11 +6498,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CONST_CONST_HAND USE_OPLINE zval *op1; - HashTable *ht = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); + HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); int result; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_exists(ht, Z_STR_P(op1)); } else if (opline->extended_value) { @@ -6495,8 +6540,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_ zval *container, *dim, *value; zend_long offset; - container = EX_CONSTANT(opline->op1); - dim = EX_CONSTANT(opline->op2); + container = RT_CONSTANT(opline, opline->op1); + dim = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_index_array: if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { @@ -6536,42 +6581,1776 @@ fetch_dim_r_index_undef: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + fast_long_sub_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2, *result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + fast_long_add_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2))); + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + add_function(EX_VAR(opline->result.var), op1, op2); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2, *result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + fast_long_sub_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2))); + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + sub_function(EX_VAR(opline->result.var), op1, op2); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + fast_div_function(EX_VAR(opline->result.var), op1, op2); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2, *result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { + SAVE_OPLINE(); + zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) { + /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */ + ZVAL_LONG(result, 0); + } else { + ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2)); + } + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + mod_function(EX_VAR(opline->result.var), op1, op2); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) + && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + shift_left_function(EX_VAR(opline->result.var), op1, op2); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) + && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + shift_right_function(EX_VAR(opline->result.var), op1, op2); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + pow_function(EX_VAR(opline->result.var), op1, op2); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + + if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + zval_ptr_dtor_nogc(free_op2); + } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + zval_ptr_dtor_nogc(free_op2); + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + zval_ptr_dtor_nogc(free_op2); + } + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + concat_function(EX_VAR(opline->result.var), op1, op2); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2, *result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + do { + int result; + + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = ((double)Z_LVAL_P(op1) < Z_DVAL_P(op2)); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = (Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2))); + } else { + break; + } + } else { + break; + } + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); + } while (0); + + SAVE_OPLINE(); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + result = EX_VAR(opline->result.var); + compare_function(result, op1, op2); + ZVAL_BOOL(result, Z_LVAL_P(result) < 0); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2, *result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + do { + int result; + + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = ((double)Z_LVAL_P(op1) <= Z_DVAL_P(op2)); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = (Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2))); + } else { + break; + } + } else { + break; + } + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); + } while (0); + + SAVE_OPLINE(); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + result = EX_VAR(opline->result.var); + compare_function(result, op1, op2); + ZVAL_BOOL(result, Z_LVAL_P(result) <= 0); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + compare_function(EX_VAR(opline->result.var), op1, op2); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *container, *dim, *value, *result; + + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (IS_CONST != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + ZVAL_COPY_UNREF(result, value); + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R_slow(result, container, dim EXECUTE_DATA_CC); + } + } else { + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R(result, container, dim, (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); + } + zval_ptr_dtor_nogc(free_op2); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *container; + + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op2); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use temporary expression in write context"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use [] for reading"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container; + zend_free_op free_op2; + zval *offset; + void **cache_slot = NULL; + + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + + if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + if (IS_CONST == IS_CONST || + (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); + } + goto fetch_obj_r_no_object; + } while (0); + } + + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zval *retval; + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } + } + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); + } + + if (UNEXPECTED(zobj->handlers->read_property == NULL)) { + zend_string *property_name; +fetch_obj_r_no_object: + property_name = zval_get_string(offset); + zend_error(E_NOTICE, "Trying to get property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + } + } + } while (0); + + zval_ptr_dtor_nogc(free_op2); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container; + zend_free_op free_op2; + zval *offset; + void **cache_slot = NULL; + + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + + if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + if (IS_CONST == IS_CONST || + (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + goto fetch_obj_is_no_object; + } while (0); + } + + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zval *retval; + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } + } + + if (UNEXPECTED(zobj->handlers->read_property == NULL)) { +fetch_obj_is_no_object: + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } + } while (0); + + zval_ptr_dtor_nogc(free_op2); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + /* Behave like FETCH_OBJ_W */ + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use temporary expression in write context"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *container; + + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + zend_fetch_dimension_address_LIST_r(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op2; zval *op1, *op2; + zend_string *op1_str, *op2_str, *str; + + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + + if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + zval_ptr_dtor_nogc(free_op2); + } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + zval_ptr_dtor_nogc(free_op2); + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + zval_ptr_dtor_nogc(free_op2); + } + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if (IS_CONST == IS_CONST) { + op1_str = Z_STR_P(op1); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + op1_str = zend_string_copy(Z_STR_P(op1)); + } else { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + op1_str = zval_get_string_func(op1); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + op2_str = Z_STR_P(op2); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + op2_str = zend_string_copy(Z_STR_P(op2)); + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + op2_str = zval_get_string_func(op2); + } + do { + if (IS_CONST != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + zend_string_release(op1_str); + break; + } + } + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + zend_string_release(op2_str); + break; + } + } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CONST != IS_CONST) { + zend_string_release(op1_str); + } + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_string_release(op2_str); + } + } while (0); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + zend_free_op free_op2; + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; + + SAVE_OPLINE(); + + object = RT_CONSTANT(opline, opline->op1); + + if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); + zval_ptr_dtor_nogc(free_op2); + + HANDLE_EXCEPTION(); + } while (0); + } + + if (IS_CONST != IS_UNUSED) { + do { + if (IS_CONST == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + object = Z_REFVAL_P(object); + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + break; + } + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = GET_OP1_UNDEF_CV(object, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); + zval_ptr_dtor_nogc(free_op2); + + HANDLE_EXCEPTION(); + } + } while (0); + } + + obj = Z_OBJ_P(object); + called_scope = obj->ce; + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + } else { + zend_object *orig_obj = obj; + + if (UNEXPECTED(obj->handlers->get_method == NULL)) { + zend_throw_error(NULL, "Object does not support method calls"); + zval_ptr_dtor_nogc(free_op2); + + HANDLE_EXCEPTION(); + } + + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); + } + zval_ptr_dtor_nogc(free_op2); + + HANDLE_EXCEPTION(); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { + init_func_run_time_cache(&fbc->op_array); + } + } + + call_info = ZEND_CALL_NESTED_FUNCTION; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + obj = NULL; + } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; + GC_ADDREF(obj); /* For $this pointer */ + } + + zval_ptr_dtor_nogc(free_op2); + + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, called_scope, obj); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + zend_class_entry *ce; + zend_object *object; + zend_function *fbc; + zend_execute_data *call; + + SAVE_OPLINE(); + + if (IS_CONST == IS_CONST) { + /* no function found. try a static method in class */ + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + } + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + + if (IS_CONST == IS_CONST && + (IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { + /* nothing to do */ + } else if (IS_CONST != IS_CONST && + (IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zend_free_op free_op2; + + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Function name must be a string"); + zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); + } while (0); + } + } + + if (ce->get_static_method) { + fbc = ce->get_static_method(ce, Z_STR_P(function_name)); + } else { + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + } + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), Z_STRVAL_P(function_name)); + } + zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { + if (IS_CONST == IS_CONST) { + CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); + } else { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); + } + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { + init_func_run_time_cache(&fbc->op_array); + } + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zval_ptr_dtor_nogc(free_op2); + } + } else { + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); + } + if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { + zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); + HANDLE_EXCEPTION(); + } + fbc = ce->constructor; + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { + init_func_run_time_cache(&fbc->op_array); + } + } + + object = NULL; + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { + object = Z_OBJ(EX(This)); + ce = object->ce; + } else { + if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { + /* Allowed for PHP 4 compatibility. */ + zend_error( + E_DEPRECATED, + "Non-static method %s::%s() should not be called statically", + ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } else { + /* An internal function assumes $this is present and won't check that. + * So PHP would crash by allowing the call. */ + zend_throw_error( + zend_ce_error, + "Non-static method %s::%s() cannot be called statically", + ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); + HANDLE_EXCEPTION(); + } + } + } + + if (IS_CONST == IS_UNUSED) { + /* previous opcode is ZEND_FETCH_CLASS */ + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if (Z_TYPE(EX(This)) == IS_OBJECT) { + ce = Z_OBJCE(EX(This)); + } else { + ce = Z_CE(EX(This)); + } + } + } + + call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, ce, object); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *function_name; + zend_fcall_info_cache fcc; + char *error = NULL; + zend_function *func; + zend_class_entry *called_scope; + zend_object *object; + zend_execute_data *call; + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; + + SAVE_OPLINE(); + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { + func = fcc.function_handler; + called_scope = fcc.called_scope; + object = fcc.object; + if (error) { + efree(error); + /* This is the only soft error is_callable() can generate */ + zend_error(E_DEPRECATED, + "Non-static method %s::%s() should not be called statically", + ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name)); + if (UNEXPECTED(EG(exception) != NULL)) { + zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); + } + } + if (func->common.fn_flags & ZEND_ACC_CLOSURE) { + /* Delay closure destruction until its invocation */ + ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT); + GC_ADDREF((zend_object*)func->common.prototype); + call_info |= ZEND_CALL_CLOSURE; + if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { + call_info |= ZEND_CALL_FAKE_CLOSURE; + } + } else if (object) { + call_info |= ZEND_CALL_RELEASE_THIS; + GC_ADDREF(object); /* For $this pointer */ + } + + zval_ptr_dtor_nogc(free_op2); + if (((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { + if (call_info & ZEND_CALL_CLOSURE) { + zend_object_release((zend_object*)func->common.prototype); + } + if (call_info & ZEND_CALL_RELEASE_THIS) { + zend_object_release(object); + } + HANDLE_EXCEPTION(); + } + + if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!func->op_array.run_time_cache)) { + init_func_run_time_cache(&func->op_array); + } + } else { + zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); + efree(error); + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + func = (zend_function*)&zend_pass_function; + called_scope = NULL; + object = NULL; + } + + call = zend_vm_stack_push_call_frame(call_info, + func, opline->extended_value, called_scope, object); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2, *result; + + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + do { + int result; + + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2)); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2))); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + zval_ptr_dtor_nogc(free_op2); + } else { + break; + } + } else { + break; + } + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); + } while (0); + + SAVE_OPLINE(); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + result = EX_VAR(opline->result.var); + compare_function(result, op1, op2); + ZVAL_BOOL(result, Z_LVAL_P(result) == 0); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *expr_ptr, new_expr; + + SAVE_OPLINE(); + if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && + UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { + expr_ptr = NULL; + ZVAL_MAKE_REF(expr_ptr); + Z_ADDREF_P(expr_ptr); + + } else { + expr_ptr = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_TMP_VAR) { + /* pass */ + } else if (IS_CONST == IS_CONST) { + Z_TRY_ADDREF_P(expr_ptr); + } else if (IS_CONST == IS_CV) { + ZVAL_DEREF(expr_ptr); + Z_TRY_ADDREF_P(expr_ptr); + } else /* if (IS_CONST == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(expr_ptr); + + expr_ptr = Z_REFVAL_P(expr_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + ZVAL_COPY_VALUE(&new_expr, expr_ptr); + expr_ptr = &new_expr; + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } + } + } + } + + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zend_free_op free_op2; + zval *offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + zend_string *str; + zend_ulong hval; + +add_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index; + } + } +str_index: + zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index: + zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto add_again; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index; + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else { + zend_error(E_WARNING, "Illegal offset type"); + zval_ptr_dtor_nogc(expr_ptr); + } + zval_ptr_dtor_nogc(free_op2); + } else { + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + zval_ptr_dtor_nogc(expr_ptr); + } + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zval *array; + uint32_t size; + USE_OPLINE + + array = EX_VAR(opline->result.var); + if (IS_CONST != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init(Z_ARRVAL_P(array), 0); + } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *container; int result; + zend_ulong hval; + zval *offset; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); + container = RT_CONSTANT(opline, opline->op1); + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + zval *value; + zend_string *str; + +isset_dim_obj_array: + ht = Z_ARRVAL_P(container); +isset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_prop; + } + } +str_index_prop: + value = zend_hash_find_ex_ind(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_prop: + value = zend_hash_index_find(ht, hval); + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + offset = Z_REFVAL_P(offset); + goto isset_again; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index_prop; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index_prop; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_prop; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_prop; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + hval = Z_RES_HANDLE_P(offset); + goto num_index_prop; + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); + str = ZSTR_EMPTY_ALLOC(); + goto str_index_prop; + } else { + zend_error(E_WARNING, "Illegal offset type in isset or empty"); + goto isset_not_found; + } + + if (opline->extended_value & ZEND_ISSET) { + /* > IS_NULL means not IS_UNDEF and not IS_NULL */ + result = value != NULL && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = (value == NULL || !i_zend_is_true(value)); + } + goto isset_dim_obj_exit; + } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto isset_dim_obj_array; + } + } + + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); + } + + if ((IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) { + if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) { + result = + ((opline->extended_value & ZEND_ISSET) == 0) ^ + Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0); + } else { + zend_error(E_NOTICE, "Trying to check element of non-array"); + goto isset_not_found; + } + } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */ + zend_long lval; + + if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + lval = Z_LVAL_P(offset); +isset_str_offset: + if (UNEXPECTED(lval < 0)) { /* Handle negative offset */ + lval += (zend_long)Z_STRLEN_P(container); + } + if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) { + if (opline->extended_value & ZEND_ISSET) { + result = 1; + } else { + result = (Z_STRVAL_P(container)[lval] == '0'); + } + } else { + goto isset_not_found; + } + } else { + if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) { + ZVAL_DEREF(offset); + } + if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ + || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ + && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { + lval = zval_get_long(offset); + goto isset_str_offset; + } + goto isset_not_found; + } + } else { +isset_not_found: + result = ((opline->extended_value & ZEND_ISSET) == 0); + } +isset_dim_obj_exit: zval_ptr_dtor_nogc(free_op2); + ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op2; - zval *op1, *op2; + zval *container; int result; + zval *offset; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); + container = RT_CONSTANT(opline, opline->op1); + + if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + if (IS_CONST == IS_CONST || + (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + goto isset_no_object; + } + } else { + goto isset_no_object; + } + } + if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { + zend_string *property_name = zval_get_string(offset); + zend_error(E_NOTICE, "Trying to check property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); +isset_no_object: + result = ((opline->extended_value & ZEND_ISSET) == 0); + } else { + result = + ((opline->extended_value & ZEND_ISSET) == 0) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + } zval_ptr_dtor_nogc(free_op2); + ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *container, *dim, *value; + zend_long offset; + + container = RT_CONSTANT(opline, opline->op1); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + offset = zval_get_long(dim); + } + ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim EXECUTE_DATA_CC); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -6605,7 +8384,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(Z zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = EX_CONSTANT(opline->op1); + value = RT_CONSTANT(opline, opline->op1); ZVAL_COPY_VALUE(&generator->value, value); if (IS_CONST == IS_CONST) { if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { @@ -6629,7 +8408,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(Z } } else { - zval *value = EX_CONSTANT(opline->op1); + zval *value = RT_CONSTANT(opline, opline->op1); /* Consts, temporary variables and references need copying */ if (IS_CONST == IS_CONST) { @@ -6708,42 +8487,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(Z ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var_deref(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var_deref(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_CONST_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE @@ -6752,9 +8495,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ zval *retval; SAVE_OPLINE(); - varname = EX_CONSTANT(opline->op1); + varname = RT_CONSTANT(opline, opline->op1); - retval = zend_fetch_static_property_address(varname, IS_CONST, opline->op2, IS_VAR, type EXECUTE_DATA_CC); + retval = zend_fetch_static_property_address(varname, IS_CONST, opline->op2, IS_VAR, type EXECUTE_DATA_CC OPLINE_CC); if (UNEXPECTED(retval == NULL)) { if (EG(exception)) { @@ -6814,43 +8557,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CONS static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval tmp, *varname; + zval *varname; + zend_string *name, *tmp_name; zend_class_entry *ce; SAVE_OPLINE(); - varname = EX_CONSTANT(opline->op1); + varname = RT_CONSTANT(opline, opline->op1); - ZVAL_UNDEF(&tmp); - if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); } - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; + name = zval_get_tmp_string(varname, &tmp_name); } if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); } } else if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } HANDLE_EXCEPTION(); @@ -6858,10 +8605,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_V } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); + zend_std_unset_static_property(ce, name); - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -6873,20 +8620,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC zval *value; int result; - zval tmp, *varname; + zval *varname; + zend_string *name, *tmp_name; zend_class_entry *ce; SAVE_OPLINE(); - varname = EX_CONSTANT(opline->op1); - ZVAL_UNDEF(&tmp); - if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; + varname = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); } if (IS_VAR == IS_CONST) { - if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -6894,22 +8642,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); } } else { if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -6919,9 +8667,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC ce = Z_CE_P(EX_VAR(opline->op2.var)); } if (IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))) == ce)) { + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -6932,14 +8680,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } } - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + value = zend_std_get_static_property(ce, name, 1); if (IS_CONST == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); } - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } is_static_prop_return: @@ -6988,7 +8736,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(Z zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = EX_CONSTANT(opline->op1); + value = RT_CONSTANT(opline, opline->op1); ZVAL_COPY_VALUE(&generator->value, value); if (IS_CONST == IS_CONST) { if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { @@ -7012,7 +8760,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(Z } } else { - zval *value = EX_CONSTANT(opline->op1); + zval *value = RT_CONSTANT(opline, opline->op1); /* Consts, temporary variables and references need copying */ if (IS_CONST == IS_CONST) { @@ -7097,26 +8845,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ zval *varname; zval *retval; - zend_string *name; + zend_string *name, *tmp_name; HashTable *target_symbol_table; SAVE_OPLINE(); - varname = EX_CONSTANT(opline->op1); + varname = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_CONST) { name = Z_STR_P(varname); } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { name = Z_STR_P(varname); - zend_string_addref(name); + tmp_name = NULL; } else { if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { GET_OP1_UNDEF_CV(varname, BP_VAR_R); } - name = zval_get_string(varname); + name = zval_get_tmp_string(varname, &tmp_name); } target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); - retval = zend_hash_find(target_symbol_table, name); + retval = zend_hash_find_ex(target_symbol_table, name, IS_CONST == IS_CONST); if (retval == NULL) { if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { zval *result; @@ -7153,7 +8901,7 @@ fetch_this: EMPTY_SWITCH_DEFAULT_CASE() } if (IS_CONST != IS_CONST) { - zend_string_release(name); + zend_tmp_string_release(tmp_name); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -7205,7 +8953,7 @@ fetch_this: } if (IS_CONST != IS_CONST) { - zend_string_release(name); + zend_tmp_string_release(tmp_name); } ZEND_ASSERT(retval != NULL); @@ -7261,9 +9009,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ zval *retval; SAVE_OPLINE(); - varname = EX_CONSTANT(opline->op1); + varname = RT_CONSTANT(opline, opline->op1); - retval = zend_fetch_static_property_address(varname, IS_CONST, opline->op2, IS_UNUSED, type EXECUTE_DATA_CC); + retval = zend_fetch_static_property_address(varname, IS_CONST, opline->op2, IS_UNUSED, type EXECUTE_DATA_CC OPLINE_CC); if (UNEXPECTED(retval == NULL)) { if (EG(exception)) { @@ -7323,40 +9071,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CONS static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zend_free_op free_op1; - - SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = NULL; - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED EXECUTE_DATA_CC); - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { if (IS_UNUSED == IS_UNUSED) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use [] for reading"); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = EX_CONSTANT(opline->op1); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, NULL, IS_UNUSED EXECUTE_DATA_CC); - - + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -7372,14 +9108,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -7394,12 +9130,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST == IS_CONST && IS_UNUSED == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { /* nothing to do */ } else if (IS_CONST != IS_CONST && IS_UNUSED == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); } else if (IS_UNUSED != IS_UNUSED) { @@ -7428,7 +9164,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { @@ -7528,7 +9264,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_ zend_arg_info *ret_info = EX(func)->common.arg_info - 1; - retval_ref = retval_ptr = EX_CONSTANT(opline->op1); + retval_ref = retval_ptr = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_CONST) { ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr); @@ -7578,24 +9314,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_U Z_ADDREF_P(expr_ptr); } else { - expr_ptr = EX_CONSTANT(opline->op1); + expr_ptr = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_TMP_VAR) { /* pass */ } else if (IS_CONST == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else if (IS_CONST == IS_CV) { ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else /* if (IS_CONST == IS_VAR) */ { if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { zend_refcounted *ref = Z_COUNTED_P(expr_ptr); expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; efree_size(ref, sizeof(zend_reference)); @@ -7647,13 +9379,13 @@ num_index: goto str_index; } else { zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -7668,47 +9400,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_H array = EX_VAR(opline->result.var); if (IS_CONST != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - - if (IS_CONST != IS_UNUSED) { + ZVAL_ARR(array, zend_new_array(size)); /* Explicitly initialize array as not-packed if flag is set */ if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init(Z_ARRVAL_P(array), 0); } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval tmp, *varname; + zval *varname; + zend_string *name, *tmp_name; HashTable *target_symbol_table; SAVE_OPLINE(); - varname = EX_CONSTANT(opline->op1); + varname = RT_CONSTANT(opline, opline->op1); - ZVAL_UNDEF(&tmp); - if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); } - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; + name = zval_get_tmp_string(varname, &tmp_name); } target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + zend_hash_del_ind(target_symbol_table, name); - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -7717,43 +9449,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval tmp, *varname; + zval *varname; + zend_string *name, *tmp_name; zend_class_entry *ce; SAVE_OPLINE(); - varname = EX_CONSTANT(opline->op1); + varname = RT_CONSTANT(opline, opline->op1); - ZVAL_UNDEF(&tmp); - if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); } - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; + name = zval_get_tmp_string(varname, &tmp_name); } if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); } } else if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } HANDLE_EXCEPTION(); @@ -7761,10 +9497,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_U } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); + zend_std_unset_static_property(ce, name); - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -7776,22 +9512,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_U zval *value; int result; - zval tmp, *varname; + zval *varname; + zend_string *name, *tmp_name; HashTable *target_symbol_table; SAVE_OPLINE(); - varname = EX_CONSTANT(opline->op1); - ZVAL_UNDEF(&tmp); - if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; + varname = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); } target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); + value = zend_hash_find_ex_ind(target_symbol_table, name, IS_CONST == IS_CONST); - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } if (opline->extended_value & ZEND_ISSET) { @@ -7812,20 +9549,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC zval *value; int result; - zval tmp, *varname; + zval *varname; + zend_string *name, *tmp_name; zend_class_entry *ce; SAVE_OPLINE(); - varname = EX_CONSTANT(opline->op1); - ZVAL_UNDEF(&tmp); - if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; + varname = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); } if (IS_UNUSED == IS_CONST) { - if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -7833,22 +9571,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); } } else { if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -7858,9 +9596,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC ce = Z_CE_P(EX_VAR(opline->op2.var)); } if (IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))) == ce)) { + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -7871,14 +9609,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } } - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + value = zend_std_get_static_property(ce, name, 1); if (IS_CONST == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); } - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } is_static_prop_return: @@ -7901,7 +9639,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_C zval *object; zend_class_entry *called_scope; - zfunc = zend_hash_find(EG(function_table), Z_STR_P(EX_CONSTANT(opline->op1))); + zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1); ZEND_ASSERT(zfunc != NULL && Z_FUNC_P(zfunc)->type == ZEND_USER_FUNCTION); if (Z_TYPE(EX(This)) == IS_OBJECT) { @@ -7955,7 +9693,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = EX_CONSTANT(opline->op1); + value = RT_CONSTANT(opline, opline->op1); ZVAL_COPY_VALUE(&generator->value, value); if (IS_CONST == IS_CONST) { if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { @@ -7979,7 +9717,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE } } else { - zval *value = EX_CONSTANT(opline->op1); + zval *value = RT_CONSTANT(opline, opline->op1); /* Consts, temporary variables and references need copying */ if (IS_CONST == IS_CONST) { @@ -8066,7 +9804,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CONST_UNUSED_HANDLE zend_long count; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); do { if (Z_TYPE_P(op1) == IS_ARRAY) { count = zend_array_count(Z_ARRVAL_P(op1)); @@ -8123,7 +9861,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_CONST_UNUSED_HA zval *op1; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); if (Z_TYPE_P(op1) == IS_OBJECT) { ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); } else { @@ -8143,7 +9881,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_CONST_UNUSED_HAN zend_string *type; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); type = zend_zval_get_type(op1); if (EXPECTED(type)) { ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); @@ -8162,7 +9900,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSE arg_count = EX_NUM_ARGS(); if (IS_CONST == IS_CONST) { - skip = Z_LVAL_P(EX_CONSTANT(opline->op1)); + skip = Z_LVAL_P(RT_CONSTANT(opline, opline->op1)); if (arg_count < skip) { result_size = 0; } else { @@ -8173,12 +9911,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSE result_size = arg_count; } - ht = (zend_array *) emalloc(sizeof(zend_array)); - zend_hash_init(ht, result_size, NULL, ZVAL_PTR_DTOR, 0); - ZVAL_ARR(EX_VAR(opline->result.var), ht); - if (result_size) { uint32_t first_extra_arg = EX(func)->op_array.num_args; + + ht = zend_new_array(result_size); + ZVAL_ARR(EX_VAR(opline->result.var), ht); zend_hash_real_init(ht, 1); ZEND_HASH_FILL_PACKED(ht) { zval *p, *q; @@ -8222,6 +9959,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSE } } ZEND_HASH_FILL_END(); ht->nNumOfElements = result_size; + } else { + ZVAL_EMPTY_ARRAY(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE(); } @@ -8232,7 +9971,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CV_HANDLER(ZEND zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { @@ -8275,7 +10014,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_CV_HANDLER(ZEND zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { @@ -8312,52 +10051,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_CV_HANDLER(ZEND ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *op1, *op2, *result; - - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - zend_long overflow; - - result = EX_VAR(opline->result.var); - ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); - Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2))); - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - mul_function(EX_VAR(opline->result.var), op1, op2); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -8365,7 +10058,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_CV_HANDLER(ZEND zval *op1, *op2; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); fast_div_function(EX_VAR(opline->result.var), op1, op2); @@ -8379,7 +10072,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_CV_HANDLER(ZEND zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { @@ -8418,7 +10111,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_CV_HANDLER(ZEND_ zval *op1, *op2; - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) @@ -8446,7 +10139,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_CV_HANDLER(ZEND_ zval *op1, *op2; - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) @@ -8475,7 +10168,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_CV_HANDLER(ZEND zval *op1, *op2; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); pow_function(EX_VAR(opline->result.var), op1, op2); @@ -8489,7 +10182,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z zval *op1, *op2; - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && @@ -8498,38 +10191,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z zend_string *op2_str = Z_STR_P(op2); zend_string *str; - do { - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - - break; - } - } - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - - break; - } + if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (IS_CONST != IS_CONST && IS_CONST != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; + } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - } while (0); + } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + } ZEND_VM_NEXT_OPCODE(); } else { SAVE_OPLINE(); @@ -8547,185 +10238,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *op1, *op2, *result; - - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - do { - int result; - - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } - - - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) == 0); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *op1, *op2, *result; - - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - do { - int result; - - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 0; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 1; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0); - } - - - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) != 0); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); do { int result; @@ -8775,7 +10294,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); do { int result; @@ -8826,7 +10345,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_CV_HANDLE zval *op1, *op2; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); compare_function(EX_VAR(opline->result.var), op1, op2); @@ -8834,102 +10353,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_CV_HANDLE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *op1, *op2; - - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - bitwise_or_function(EX_VAR(opline->result.var), op1, op2); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *op1, *op2; - - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - bitwise_and_function(EX_VAR(opline->result.var), op1, op2); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *op1, *op2; - - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - bitwise_xor_function(EX_VAR(opline->result.var), op1, op2); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - boolean_xor_function(EX_VAR(opline->result.var), op1, op2); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -8937,7 +10360,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HAND zval *container, *dim, *value, *result; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); + container = RT_CONSTANT(opline, opline->op1); dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (IS_CONST != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -8973,7 +10396,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_CV_HAN zval *container; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); + container = RT_CONSTANT(opline, opline->op1); zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); @@ -8983,40 +10406,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_CV_HAN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zend_free_op free_op1; - - SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = NULL; - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { if (IS_CV == IS_UNUSED) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use [] for reading"); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = EX_CONSTANT(opline->op1); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); - - + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -9026,26 +10437,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HAND zval *container; zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); + container = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (IS_CONST == IS_CONST || (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_r_no_object; + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - } else { goto fetch_obj_r_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -9053,23 +10472,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HAND zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (IS_CV == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if (IS_CV == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } } } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (UNEXPECTED(zobj->handlers->read_property == NULL)) { @@ -9080,7 +10523,7 @@ fetch_obj_r_no_object: zend_string_release(property_name); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); @@ -9099,26 +10542,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HAN zval *container; zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); + container = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); if (IS_CONST == IS_CONST || (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_is_no_object; + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } } - } else { goto fetch_obj_is_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -9126,21 +10571,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HAN zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (IS_CV == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if (IS_CV == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } } } } @@ -9150,7 +10617,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -9165,48 +10632,33 @@ fetch_obj_is_no_object: static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1; - zval *property; - - SAVE_OPLINE(); - container = NULL; - - if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); - zend_fetch_dimension_address_read_LIST(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC) EXECUTE_DATA_CC); + container = RT_CONSTANT(opline, opline->op1); + zend_fetch_dimension_address_LIST_r(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC) EXECUTE_DATA_CC); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -9219,7 +10671,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HAND zend_string *op1_str, *op2_str, *str; - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { @@ -9227,38 +10679,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HAND zend_string *op2_str = Z_STR_P(op2); zend_string *str; - do { - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - - break; - } - } - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - - break; - } + if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (IS_CONST != IS_CONST && IS_CONST != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; + } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - } while (0); + } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + + } ZEND_VM_NEXT_OPCODE(); } @@ -9271,7 +10721,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HAND if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - op1_str = _zval_get_string_func(op1); + op1_str = zval_get_string_func(op1); } if (IS_CV == IS_CONST) { op2_str = Z_STR_P(op2); @@ -9281,13 +10731,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HAND if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { GET_OP2_UNDEF_CV(op2, BP_VAR_R); } - op2_str = _zval_get_string_func(op2); + op2_str = zval_get_string_func(op2); } do { if (IS_CONST != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { if (IS_CV == IS_CONST) { - zend_string_addref(op2_str); + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } } ZVAL_STR(EX_VAR(opline->result.var), op2_str); zend_string_release(op1_str); @@ -9297,7 +10749,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HAND if (IS_CV != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { if (IS_CONST == IS_CONST) { - zend_string_addref(op1_str); + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } } ZVAL_STR(EX_VAR(opline->result.var), op1_str); zend_string_release(op2_str); @@ -9334,7 +10788,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV SAVE_OPLINE(); - object = EX_CONSTANT(opline->op1); + object = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -9405,7 +10859,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV } /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); @@ -9431,7 +10885,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(obj)++; /* For $this pointer */ + GC_ADDREF(obj); /* For $this pointer */ } @@ -9460,14 +10914,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -9482,12 +10936,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST == IS_CONST && IS_CV == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { /* nothing to do */ } else if (IS_CONST != IS_CONST && IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); } else if (IS_CV != IS_UNUSED) { @@ -9516,7 +10970,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { @@ -9635,14 +11089,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H if (func->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT); - GC_REFCOUNT((zend_object*)func->common.prototype)++; + GC_ADDREF((zend_object*)func->common.prototype); call_info |= ZEND_CALL_CLOSURE; if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { call_info |= ZEND_CALL_FAKE_CLOSURE; } } else if (object) { call_info |= ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(object)++; /* For $this pointer */ + GC_ADDREF(object); /* For $this pointer */ } if ((IS_CV & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { @@ -9659,7 +11113,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H init_func_run_time_cache(&func->op_array); } } else { - zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(EX_CONSTANT(opline->op1)), error); + zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); efree(error); if (UNEXPECTED(EG(exception))) { @@ -9692,11 +11146,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_CV_HANDLER(ZE ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); ZEND_VM_CONTINUE(); } - catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(catch_ce == NULL)) { - catch_ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); + catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), catch_ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), catch_ce); } ce = EG(exception)->ce; @@ -9725,7 +11179,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_CV_HANDLER(ZE zval_ptr_dtor(ex); ZVAL_OBJ(ex, EG(exception)); if (UNEXPECTED(EG(exception) != exception)) { - GC_REFCOUNT(EG(exception))++; + GC_ADDREF(EG(exception)); HANDLE_EXCEPTION(); } else { EG(exception) = NULL; @@ -9739,7 +11193,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CV_HANDLER(ZEN zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); + op1 = RT_CONSTANT(opline, opline->op1); op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); do { int result; @@ -9762,17 +11216,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CV_HANDLER(ZEN } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); } else { break; @@ -9813,24 +11257,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C Z_ADDREF_P(expr_ptr); } else { - expr_ptr = EX_CONSTANT(opline->op1); + expr_ptr = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_TMP_VAR) { /* pass */ } else if (IS_CONST == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else if (IS_CONST == IS_CV) { ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else /* if (IS_CONST == IS_VAR) */ { if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { zend_refcounted *ref = Z_COUNTED_P(expr_ptr); expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; efree_size(ref, sizeof(zend_reference)); @@ -9882,13 +11322,13 @@ num_index: goto str_index; } else { zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -9903,20 +11343,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDL array = EX_VAR(opline->result.var); if (IS_CONST != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - - if (IS_CONST != IS_UNUSED) { + ZVAL_ARR(array, zend_new_array(size)); /* Explicitly initialize array as not-packed if flag is set */ if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init(Z_ARRVAL_P(array), 0); } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -9929,7 +11365,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON zval *offset; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); + container = RT_CONSTANT(opline, opline->op1); offset = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -9948,7 +11384,7 @@ isset_again: } } str_index_prop: - value = zend_hash_find_ind(ht, str); + value = zend_hash_find_ex_ind(ht, str, IS_CV == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: @@ -10060,7 +11496,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CO zval *offset; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); + container = RT_CONSTANT(opline, opline->op1); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -10130,7 +11566,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = EX_CONSTANT(opline->op1); + value = RT_CONSTANT(opline, opline->op1); ZVAL_COPY_VALUE(&generator->value, value); if (IS_CONST == IS_CONST) { if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { @@ -10154,7 +11590,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE } } else { - zval *value = EX_CONSTANT(opline->op1); + zval *value = RT_CONSTANT(opline, opline->op1); /* Consts, temporary variables and references need copying */ if (IS_CONST == IS_CONST) { @@ -10240,7 +11676,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_ zval *container, *dim, *value; zend_long offset; - container = EX_CONSTANT(opline->op1); + container = RT_CONSTANT(opline, opline->op1); dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_index_array: @@ -10281,14 +11717,1706 @@ fetch_dim_r_index_undef: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + Z_LVAL_P(var_ptr)++; + if (UNEXPECTED(0)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + Z_LVAL_P(var_ptr)++; + if (UNEXPECTED(1)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + fast_long_increment_function(var_ptr); + if (UNEXPECTED(0)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + fast_long_increment_function(var_ptr); + if (UNEXPECTED(1)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_increment_function(var_ptr); + } else { + Z_DVAL_P(var_ptr)++; + } + if (UNEXPECTED(0)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_increment_function(var_ptr); + } else { + Z_DVAL_P(var_ptr)++; + } + if (UNEXPECTED(1)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + Z_LVAL_P(var_ptr)--; + if (UNEXPECTED(0)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + Z_LVAL_P(var_ptr)--; + if (UNEXPECTED(1)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + fast_long_decrement_function(var_ptr); + if (UNEXPECTED(0)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + fast_long_decrement_function(var_ptr); + if (UNEXPECTED(1)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_decrement_function(var_ptr); + } else { + Z_DVAL_P(var_ptr)--; + } + if (UNEXPECTED(0)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_decrement_function(var_ptr); + } else { + Z_DVAL_P(var_ptr)--; + } + if (UNEXPECTED(1)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + Z_LVAL_P(var_ptr)++; + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_LONG_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + fast_long_increment_function(var_ptr); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_increment_function(var_ptr); + } else { + Z_DVAL_P(var_ptr)++; + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + Z_LVAL_P(var_ptr)--; + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_LONG_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + fast_long_decrement_function(var_ptr); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_decrement_function(var_ptr); + } else { + Z_DVAL_P(var_ptr)--; + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *value; + + value = EX_VAR(opline->op1.var); + ZVAL_DOUBLE(EX_VAR(opline->result.var), Z_DVAL_P(value)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *value; + + value = EX_VAR(opline->op1.var); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + fast_long_add_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + fast_long_sub_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) * Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + zend_long overflow; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); + Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + fast_long_add_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + fast_long_sub_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) * Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + zend_long overflow; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); + Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *op1; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1)); + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + bitwise_not_function(EX_VAR(opline->result.var), + _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + zend_free_op free_op1; + + val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(val, BP_VAR_R); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } else { + SAVE_OPLINE(); + ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val)); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *z; + + SAVE_OPLINE(); + z = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (Z_TYPE_P(z) == IS_STRING) { + zend_string *str = Z_STR_P(z); + + if (ZSTR_LEN(str) != 0) { + zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); + } + } else { + zend_string *str = zval_get_string_func(z); + + if (ZSTR_LEN(str) != 0) { + zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(z, BP_VAR_R); + } + zend_string_release(str); + } + + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *val; + + val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZEND_VM_SET_NEXT_OPCODE(opline + 1); + ZEND_VM_CONTINUE(); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(val, BP_VAR_R); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + } else { + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); + } + } + + SAVE_OPLINE(); + if (i_zend_is_true(val)) { + opline++; + } else { + opline = OP_JMP_ADDR(opline, opline->op2); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_JMP(opline); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *val; + + val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(val, BP_VAR_R); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if (i_zend_is_true(val)) { + opline = OP_JMP_ADDR(opline, opline->op2); + } else { + opline++; + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_JMP(opline); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *val; + + val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_INFO_P(val) == IS_TRUE)) { + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(val, BP_VAR_R); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + } else { + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); + } + } + + SAVE_OPLINE(); + if (i_zend_is_true(val)) { + opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); + } else { + opline = OP_JMP_ADDR(opline, opline->op2); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_JMP(opline); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *val; + int ret; + + val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(val, BP_VAR_R); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + } else { + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); + } + } + + SAVE_OPLINE(); + ret = i_zend_is_true(val); + zval_ptr_dtor_nogc(free_op1); + if (ret) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + opline++; + } else { + ZVAL_FALSE(EX_VAR(opline->result.var)); + opline = OP_JMP_ADDR(opline, opline->op2); + } + ZEND_VM_JMP(opline); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *val; + int ret; + + val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); + ZEND_VM_CONTINUE(); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(val, BP_VAR_R); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + ret = i_zend_is_true(val); + zval_ptr_dtor_nogc(free_op1); + if (ret) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + opline = OP_JMP_ADDR(opline, opline->op2); + } else { + ZVAL_FALSE(EX_VAR(opline->result.var)); + opline++; + } + ZEND_VM_JMP(opline); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + SAVE_OPLINE(); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zval *var; + USE_OPLINE + + SAVE_OPLINE(); + var = EX_VAR(opline->op1.var); + if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) { + zend_hash_iterator_del(Z_FE_ITER_P(var)); + } + zval_ptr_dtor_nogc(var); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value, *arg; + zend_free_op free_op1; + + value = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + ZVAL_COPY_VALUE(arg, value); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { + Z_ADDREF_P(arg); + } + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + zend_free_op free_op1; + + val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(val, BP_VAR_R); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } else { + SAVE_OPLINE(); + ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val)); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *obj; + zend_class_entry *ce, *scope; + zend_function *clone; + zend_object_clone_obj_t clone_call; + + SAVE_OPLINE(); + obj = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + do { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) { + obj = Z_REFVAL_P(obj); + if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) { + break; + } + } + ZVAL_UNDEF(EX_VAR(opline->result.var)); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(obj, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "__clone method called on non-object"); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + } while (0); + + ce = Z_OBJCE_P(obj); + clone = ce->clone; + clone_call = Z_OBJ_HT_P(obj)->clone_obj; + if (UNEXPECTED(clone_call == NULL)) { + zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); + zval_ptr_dtor_nogc(free_op1); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + + if (clone) { + if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) { + /* Ensure that if we're calling a private function, we're allowed to do so. + */ + scope = EX(func)->op_array.scope; + if (!zend_check_private(clone, scope, clone->common.function_name)) { + zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : ""); + zval_ptr_dtor_nogc(free_op1); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) { + /* Ensure that if we're calling a protected function, we're allowed to do so. + */ + scope = EX(func)->op_array.scope; + if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) { + zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : ""); + zval_ptr_dtor_nogc(free_op1); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } + } + + ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); + + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_op_array *new_op_array; + zend_free_op free_op1; + zval *inc_filename; + + SAVE_OPLINE(); + inc_filename = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + new_op_array = zend_include_or_eval(inc_filename, opline->extended_value); + zval_ptr_dtor_nogc(free_op1); + if (UNEXPECTED(EG(exception) != NULL)) { + if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) { + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); + } + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else if (new_op_array == ZEND_FAKE_OP_ARRAY) { + if (RETURN_VALUE_USED(opline)) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + } + } else if (EXPECTED(new_op_array != NULL)) { + zval *return_value = NULL; + zend_execute_data *call; + + if (RETURN_VALUE_USED(opline)) { + return_value = EX_VAR(opline->result.var); + ZVAL_NULL(return_value); + } + + new_op_array->scope = EX(func)->op_array.scope; + + call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, + (zend_function*)new_op_array, 0, + Z_TYPE(EX(This)) != IS_OBJECT ? Z_CE(EX(This)) : NULL, + Z_TYPE(EX(This)) == IS_OBJECT ? Z_OBJ(EX(This)) : NULL); + + if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { + call->symbol_table = EX(symbol_table); + } else { + call->symbol_table = zend_rebuild_symbol_table(); + } + + call->prev_execute_data = execute_data; + i_init_code_execute_data(call, new_op_array, return_value); + if (EXPECTED(zend_execute_ex == execute_ex)) { + ZEND_VM_ENTER(); + } else { + ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); + zend_execute_ex(call); + zend_vm_stack_free_call_frame(call); + } + + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + } else if (RETURN_VALUE_USED(opline)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + } + ZEND_VM_SET_OPCODE(opline + 1); + ZEND_VM_CONTINUE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zend_free_op free_op1; + zval *ptr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + do { + if (Z_TYPE_P(ptr) == IS_LONG) { + EG(exit_status) = Z_LVAL_P(ptr); + } else { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(ptr)) { + ptr = Z_REFVAL_P(ptr); + if (Z_TYPE_P(ptr) == IS_LONG) { + EG(exit_status) = Z_LVAL_P(ptr); + break; + } + } + zend_print_variable(ptr); + } + } while (0); + zval_ptr_dtor_nogc(free_op1); + } + zend_bailout(); + ZEND_VM_NEXT_OPCODE(); /* Never reached */ +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + zend_free_op free_op1; + + value = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE(); + } else { + zend_bool strict; + + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { + value = Z_REFVAL_P(value); + if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + value = GET_OP1_UNDEF_CV(value, BP_VAR_R); + } + strict = EX_USES_STRICT_TYPES(); + do { + if (EXPECTED(!strict)) { + zend_string *str; + zval tmp; + + ZVAL_COPY(&tmp, value); + if (zend_parse_arg_str_weak(&tmp, &str)) { + ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str)); + zval_ptr_dtor(&tmp); + break; + } + zval_ptr_dtor(&tmp); + } + zend_internal_type_error(strict, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value))); + ZVAL_NULL(EX_VAR(opline->result.var)); + } while (0); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *op1, *op2, *result; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { result = EX_VAR(opline->result.var); @@ -10312,26 +13440,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMPVAR_HANDLER( } SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } add_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { result = EX_VAR(opline->result.var); @@ -10355,26 +13483,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_TMPVAR_HANDLER( } SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } sub_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { zend_long overflow; @@ -10401,41 +13529,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CONST_TMPVAR_HANDLER( } SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } mul_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); fast_div_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { result = EX_VAR(opline->result.var); @@ -10455,26 +13583,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_TMPVAR_HANDLER( } SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } mod_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2; - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { @@ -10483,26 +13611,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_TMPVAR_HANDLER(Z } SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } shift_left_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2; - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { @@ -10511,105 +13639,103 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CONST_TMPVAR_HANDLER(Z } SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } shift_right_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); pow_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2; - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); - if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; - do { - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - - break; - } + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (IS_CONST != IS_CONST && IS_CONST != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; + zval_ptr_dtor_nogc(free_op1); + } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - } while (0); - zval_ptr_dtor_nogc(free_op2); + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + zval_ptr_dtor_nogc(free_op1); + + } ZEND_VM_NEXT_OPCODE(); } else { SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } concat_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); do { int result; @@ -10631,19 +13757,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_TMPVAR_HAN } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); } else { break; } @@ -10656,28 +13772,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_TMPVAR_HAN } while (0); SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } result = EX_VAR(opline->result.var); compare_function(result, op1, op2); ZVAL_BOOL(result, Z_LVAL_P(result) == 0); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); do { int result; @@ -10699,19 +13815,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_TMPVAR } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 0; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 1; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0); - } + result = !zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); } else { break; } @@ -10724,28 +13830,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_TMPVAR } while (0); SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } result = EX_VAR(opline->result.var); compare_function(result, op1, op2); ZVAL_BOOL(result, Z_LVAL_P(result) != 0); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); do { int result; @@ -10774,28 +13880,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_TMPVAR_H } while (0); SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } result = EX_VAR(opline->result.var); compare_function(result, op1, op2); ZVAL_BOOL(result, Z_LVAL_P(result) < 0); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); do { int result; @@ -10824,43 +13930,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST } while (0); SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } result = EX_VAR(opline->result.var); compare_function(result, op1, op2); ZVAL_BOOL(result, Z_LVAL_P(result) <= 0); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); compare_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2; - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); @@ -10868,26 +13974,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_TMPVAR_HANDLE } SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } bitwise_or_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2; - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); @@ -10895,26 +14001,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_TMPVAR_HANDL } SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } bitwise_and_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2; - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); @@ -10922,46 +14028,115 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_TMPVAR_HANDL } SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } bitwise_xor_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2; SAVE_OPLINE(); - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); boolean_xor_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; + zval *varname; + zval *retval; + + SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + retval = zend_fetch_static_property_address(varname, (IS_TMP_VAR|IS_VAR), opline->op2, IS_CONST, type EXECUTE_DATA_CC OPLINE_CC); + + if (UNEXPECTED(retval == NULL)) { + if (EG(exception)) { + zval_ptr_dtor_nogc(free_op1); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } else { + ZEND_ASSERT(type == BP_VAR_IS); + retval = &EG(uninitialized_zval); + } + } + + zval_ptr_dtor_nogc(free_op1); + + if (type == BP_VAR_R || type == BP_VAR_IS) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + } else { + ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } else { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; zval *container, *dim, *value, *result; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (IS_CONST != IS_CONST) { + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + dim = RT_CONSTANT(opline, opline->op2); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R EXECUTE_DATA_CC); + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); ZVAL_COPY_UNREF(result, value); } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { @@ -10978,93 +14153,62 @@ fetch_dim_r_slow: } } else { result = EX_VAR(opline->result.var); - zend_fetch_dimension_address_read_R(result, container, dim, (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); + zend_fetch_dimension_address_read_R(result, container, dim, IS_CONST EXECUTE_DATA_CC); } - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *container; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, RT_CONSTANT(opline, opline->op2), IS_CONST EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zend_free_op free_op1; zval *container; - zend_free_op free_op1, free_op2; - - SAVE_OPLINE(); - if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { - zend_throw_error(NULL, "Cannot use temporary expression in write context"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - container = NULL; - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - zval_ptr_dtor_nogc(free_op2); - - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_throw_error(NULL, "Cannot use [] for reading"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - container = EX_CONSTANT(opline->op1); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); - - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *container; - zend_free_op free_op2; zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + offset = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST || - (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_r_no_object; + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - } else { goto fetch_obj_r_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -11072,23 +14216,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_ zend_object *zobj = Z_OBJ_P(container); zval *retval; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if (IS_CONST == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } } } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (UNEXPECTED(zobj->handlers->read_property == NULL)) { @@ -11099,7 +14267,7 @@ fetch_obj_r_no_object: zend_string_release(property_name); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); @@ -11107,38 +14275,39 @@ fetch_obj_r_no_object: } } while (0); - zval_ptr_dtor_nogc(free_op2); - + zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op1; zval *container; - zend_free_op free_op2; + zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + offset = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST || - (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_is_no_object; + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } } - } else { goto fetch_obj_is_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -11146,21 +14315,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR zend_object *zobj = Z_OBJ_P(container); zval *retval; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if (IS_CONST == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } } } } @@ -11170,7 +14361,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -11178,147 +14369,112 @@ fetch_obj_is_no_object: } } while (0); - zval_ptr_dtor_nogc(free_op2); - + zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - - if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1, free_op2; - zval *property; - - SAVE_OPLINE(); - container = NULL; - - if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { - zend_throw_error(NULL, "Cannot use temporary expression in write context"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - zval_ptr_dtor_nogc(free_op2); - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *container; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); - zend_fetch_dimension_address_read_LIST(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + zend_fetch_dimension_address_LIST_r(EX_VAR(opline->result.var), container, RT_CONSTANT(opline, opline->op2) EXECUTE_DATA_CC); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1; zval *op1, *op2; zend_string *op1_str, *op2_str, *str; - op1 = EX_CONSTANT(opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; - do { - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - - break; - } + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (IS_CONST != IS_CONST && IS_CONST != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; + zval_ptr_dtor_nogc(free_op1); + } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - } while (0); - zval_ptr_dtor_nogc(free_op2); + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + zval_ptr_dtor_nogc(free_op1); + + } ZEND_VM_NEXT_OPCODE(); } SAVE_OPLINE(); - if (IS_CONST == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { op1_str = Z_STR_P(op1); } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { op1_str = zend_string_copy(Z_STR_P(op1)); } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - op1_str = _zval_get_string_func(op1); + op1_str = zval_get_string_func(op1); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_CONST == IS_CONST) { op2_str = Z_STR_P(op2); } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { op2_str = zend_string_copy(Z_STR_P(op2)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { GET_OP2_UNDEF_CV(op2, BP_VAR_R); } - op2_str = _zval_get_string_func(op2); + op2_str = zval_get_string_func(op2); } do { - if (IS_CONST != IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_string_addref(op2_str); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } } ZVAL_STR(EX_VAR(opline->result.var), op2_str); zend_string_release(op1_str); break; } } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CONST != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CONST == IS_CONST) { - zend_string_addref(op1_str); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } } ZVAL_STR(EX_VAR(opline->result.var), op1_str); zend_string_release(op2_str); @@ -11329,23 +14485,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_ memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CONST != IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_string_release(op1_str); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CONST != IS_CONST) { zend_string_release(op2_str); } } while (0); + zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; - zend_free_op free_op2; + zend_free_op free_op1; zval *object; zend_function *fbc; zend_class_entry *called_scope; @@ -11355,55 +14511,55 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM SAVE_OPLINE(); - object = EX_CONSTANT(opline->op1); + object = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + function_name = RT_CONSTANT(opline, opline->op2); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && + if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { GET_OP2_UNDEF_CV(function_name, BP_VAR_R); if (UNEXPECTED(EG(exception) != NULL)) { - + zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } } zend_throw_error(NULL, "Method name must be a string"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } while (0); } - if (IS_CONST != IS_UNUSED) { + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { do { - if (IS_CONST == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { object = Z_REFVAL_P(object); if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { break; } } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { object = GET_OP1_UNDEF_CV(object, BP_VAR_R); if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); } } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } } while (0); @@ -11412,7 +14568,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM obj = Z_OBJ_P(object); called_scope = obj->ce; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CONST == IS_CONST && EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); } else { @@ -11420,22 +14576,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM if (UNEXPECTED(obj->handlers->get_method == NULL)) { zend_throw_error(NULL, "Object does not support method calls"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); } - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CONST == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { @@ -11449,15 +14605,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM call_info = ZEND_CALL_NESTED_FUNCTION; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { obj = NULL; - } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { + } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(obj)++; /* For $this pointer */ + GC_ADDREF(obj); /* For $this pointer */ } - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } @@ -11469,245 +14625,876 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; + zend_free_op free_op1; + zval *op1, *op2, *result; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + do { + int result; + + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2)); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2))); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + + } else { + break; + } + } else { + break; + } + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); + } while (0); + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + result = EX_VAR(opline->result.var); + compare_function(result, op1, op2); + ZVAL_BOOL(result, Z_LVAL_P(result) == 0); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varname; + zend_string *name, *tmp_name; zend_class_entry *ce; - zend_object *object; - zend_function *fbc; - zend_execute_data *call; + zend_free_op free_op1; SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + if (IS_CONST == IS_CONST) { - /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); } } else if (IS_CONST == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); + ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + zend_std_unset_static_property(ce, name); - if (IS_CONST == IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { - /* nothing to do */ - } else if (IS_CONST != IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); - } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zend_free_op free_op2; + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Function name must be a string"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } while (0); - } - } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + int result; + zend_free_op free_op1; + zval *varname; + zend_string *name, *tmp_name; + zend_class_entry *ce; - if (ce->get_static_method) { - fbc = ce->get_static_method(ce, Z_STR_P(function_name)); - } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + + if (IS_CONST == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + goto is_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); } - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), Z_STRVAL_P(function_name)); + } else { + if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (IS_CONST == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { + + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; } + + goto is_static_prop_return; } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { - init_func_run_time_cache(&fbc->op_array); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(free_op2); - } - } else { - if (UNEXPECTED(ce->constructor == NULL)) { - zend_throw_error(NULL, "Cannot call constructor"); - HANDLE_EXCEPTION(); + } + + value = zend_std_get_static_property(ce, name, 1); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); + } + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); + +is_static_prop_return: + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container; + int result; + zend_ulong hval; + zval *offset; + + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + offset = RT_CONSTANT(opline, opline->op2); + + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + zval *value; + zend_string *str; + +isset_dim_obj_array: + ht = Z_ARRVAL_P(container); +isset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_CONST != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_prop; + } + } +str_index_prop: + value = zend_hash_find_ex_ind(ht, str, IS_CONST == IS_CONST); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_prop: + value = zend_hash_index_find(ht, hval); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + offset = Z_REFVAL_P(offset); + goto isset_again; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index_prop; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index_prop; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_prop; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_prop; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + hval = Z_RES_HANDLE_P(offset); + goto num_index_prop; + } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); + str = ZSTR_EMPTY_ALLOC(); + goto str_index_prop; + } else { + zend_error(E_WARNING, "Illegal offset type in isset or empty"); + goto isset_not_found; } - if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { - zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); - HANDLE_EXCEPTION(); + + if (opline->extended_value & ZEND_ISSET) { + /* > IS_NULL means not IS_UNDEF and not IS_NULL */ + result = value != NULL && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = (value == NULL || !i_zend_is_true(value)); } - fbc = ce->constructor; - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { - init_func_run_time_cache(&fbc->op_array); + goto isset_dim_obj_exit; + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto isset_dim_obj_array; } } - object = NULL; - if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { - if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - object = Z_OBJ(EX(This)); - ce = object->ce; + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); + } + + if (((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) { + if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) { + result = + ((opline->extended_value & ZEND_ISSET) == 0) ^ + Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0); } else { - if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - /* Allowed for PHP 4 compatibility. */ - zend_error( - E_DEPRECATED, - "Non-static method %s::%s() should not be called statically", - ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + zend_error(E_NOTICE, "Trying to check element of non-array"); + goto isset_not_found; + } + } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */ + zend_long lval; + + if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + lval = Z_LVAL_P(offset); +isset_str_offset: + if (UNEXPECTED(lval < 0)) { /* Handle negative offset */ + lval += (zend_long)Z_STRLEN_P(container); + } + if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) { + if (opline->extended_value & ZEND_ISSET) { + result = 1; + } else { + result = (Z_STRVAL_P(container)[lval] == '0'); } } else { - /* An internal function assumes $this is present and won't check that. - * So PHP would crash by allowing the call. */ - zend_throw_error( - zend_ce_error, - "Non-static method %s::%s() cannot be called statically", - ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); - HANDLE_EXCEPTION(); + goto isset_not_found; + } + } else { + if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(offset); } + if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ + || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ + && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { + lval = zval_get_long(offset); + goto isset_str_offset; + } + goto isset_not_found; } + } else { +isset_not_found: + result = ((opline->extended_value & ZEND_ISSET) == 0); } - if (IS_CONST == IS_UNUSED) { - /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { - if (Z_TYPE(EX(This)) == IS_OBJECT) { - ce = Z_OBJCE(EX(This)); - } else { - ce = Z_CE(EX(This)); +isset_dim_obj_exit: + + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container; + int result; + zval *offset; + + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + offset = RT_CONSTANT(opline, opline->op2); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + goto isset_no_object; } + } else { + goto isset_no_object; } } + if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { + zend_string *property_name = zval_get_string(offset); + zend_error(E_NOTICE, "Trying to check property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); +isset_no_object: + result = ((opline->extended_value & ZEND_ISSET) == 0); + } else { + result = + ((opline->extended_value & ZEND_ISSET) == 0) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, ce, object); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; - zval *function_name; - zend_fcall_info_cache fcc; - char *error = NULL; - zend_function *func; - zend_class_entry *called_scope; - zend_object *object; - zend_execute_data *call; - uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; + zend_free_op free_op1; + zval *expr; + zend_bool result; SAVE_OPLINE(); - function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { - func = fcc.function_handler; - called_scope = fcc.called_scope; - object = fcc.object; - if (error) { - efree(error); - /* This is the only soft error is_callable() can generate */ - zend_error(E_DEPRECATED, - "Non-static method %s::%s() should not be called statically", - ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name)); - if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op2); + expr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; + + if (IS_CONST == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (EXPECTED(ce)) { + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + } + } + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + zval_ptr_dtor_nogc(free_op1); + ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - if (func->common.fn_flags & ZEND_ACC_CLOSURE) { - /* Delay closure destruction until its invocation */ - ZEND_ASSERT(GC_TYPE((zend_object*)func->common.prototype) == IS_OBJECT); - GC_REFCOUNT((zend_object*)func->common.prototype)++; - call_info |= ZEND_CALL_CLOSURE; - if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { - call_info |= ZEND_CALL_FAKE_CLOSURE; - } - } else if (object) { - call_info |= ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(object)++; /* For $this pointer */ + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(expr, BP_VAR_R); } + result = 0; + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - zval_ptr_dtor_nogc(free_op2); - if (((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { - if (call_info & ZEND_CALL_CLOSURE) { - zend_object_release((zend_object*)func->common.prototype); - } - if (call_info & ZEND_CALL_RELEASE_THIS) { - zend_object_release(object); +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *op, *jump_zv; + HashTable *jumptable; + + op = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); + + if (Z_TYPE_P(op) != IS_LONG) { + ZVAL_DEREF(op); + if (Z_TYPE_P(op) != IS_LONG) { + /* Wrong type, fall back to ZEND_CASE chain */ + ZEND_VM_NEXT_OPCODE(); + } + } + + jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op)); + if (jump_zv != NULL) { + ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); + ZEND_VM_CONTINUE(); + } else { + /* default */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *op, *jump_zv; + HashTable *jumptable; + + op = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); + + if (Z_TYPE_P(op) != IS_STRING) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + /* Wrong type, fall back to ZEND_CASE chain */ + ZEND_VM_NEXT_OPCODE(); + } else { + ZVAL_DEREF(op); + if (Z_TYPE_P(op) != IS_STRING) { + /* Wrong type, fall back to ZEND_CASE chain */ + ZEND_VM_NEXT_OPCODE(); } - HANDLE_EXCEPTION(); } + } - if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!func->op_array.run_time_cache)) { - init_func_run_time_cache(&func->op_array); + jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), (IS_TMP_VAR|IS_VAR) == IS_CONST); + if (jump_zv != NULL) { + ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); + ZEND_VM_CONTINUE(); + } else { + /* default */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); + } +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container, *dim, *value; + zend_long offset; + + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + dim = RT_CONSTANT(opline, opline->op2); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + offset = zval_get_long(dim); + } + ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); + if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; } } else { - zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(EX_CONSTANT(opline->op1)), error); - efree(error); - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); +fetch_dim_r_index_slow: + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2, *result; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + fast_long_add_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2))); + ZEND_VM_NEXT_OPCODE(); } - func = (zend_function*)&zend_pass_function; - called_scope = NULL; - object = NULL; } - call = zend_vm_stack_push_call_frame(call_info, - func, opline->extended_value, called_scope, object); - call->prev_execute_data = EX(call); - EX(call) = call; + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + add_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - ZEND_VM_NEXT_OPCODE(); +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2, *result; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + fast_long_sub_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2))); + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + sub_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1, free_op2; zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + zend_long overflow; + + result = EX_VAR(opline->result.var); + ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); + Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2))); + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + mul_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + fast_div_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2, *result; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { + SAVE_OPLINE(); + zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) { + /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */ + ZVAL_LONG(result, 0); + } else { + ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2)); + } + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + mod_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) + && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + shift_left_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) + && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + shift_right_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + pow_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + zval_ptr_dtor_nogc(free_op1); + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + zval_ptr_dtor_nogc(free_op2); + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + zval_ptr_dtor_nogc(free_op2); + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + } + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + concat_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2, *result; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { int result; @@ -11730,17 +15517,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + zval_ptr_dtor_nogc(free_op1); zval_ptr_dtor_nogc(free_op2); } else { break; @@ -11754,7 +15532,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER } while (0); SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { @@ -11763,141 +15541,851 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER result = EX_VAR(opline->result.var); compare_function(result, op1, op2); ZVAL_BOOL(result, Z_LVAL_P(result) == 0); + zval_ptr_dtor_nogc(free_op1); zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2, *result; - zval *expr_ptr, new_expr; + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + do { + int result; + + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2)); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2))); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + result = !zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + } else { + break; + } + } else { + break; + } + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); + } while (0); SAVE_OPLINE(); - if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && - UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = NULL; - ZVAL_MAKE_REF(expr_ptr); - Z_ADDREF_P(expr_ptr); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + result = EX_VAR(opline->result.var); + compare_function(result, op1, op2); + ZVAL_BOOL(result, Z_LVAL_P(result) != 0); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2, *result; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + do { + int result; + + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = ((double)Z_LVAL_P(op1) < Z_DVAL_P(op2)); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = (Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2))); + } else { + break; + } + } else { + break; + } + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); + } while (0); + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + result = EX_VAR(opline->result.var); + compare_function(result, op1, op2); + ZVAL_BOOL(result, Z_LVAL_P(result) < 0); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2, *result; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + do { + int result; + + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = ((double)Z_LVAL_P(op1) <= Z_DVAL_P(op2)); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = (Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2))); + } else { + break; + } + } else { + break; + } + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); + } while (0); + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + result = EX_VAR(opline->result.var); + compare_function(result, op1, op2); + ZVAL_BOOL(result, Z_LVAL_P(result) <= 0); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + compare_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + bitwise_or_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + bitwise_and_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + bitwise_xor_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + boolean_xor_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *container, *dim, *value, *result; + + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + ZVAL_COPY_UNREF(result, value); + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R_slow(result, container, dim EXECUTE_DATA_CC); + } } else { - expr_ptr = EX_CONSTANT(opline->op1); - if (IS_CONST == IS_TMP_VAR) { - /* pass */ - } else if (IS_CONST == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R(result, container, dim, (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); + } + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *container; + + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container; + zend_free_op free_op2; + zval *offset; + void **cache_slot = NULL; + + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } } - } else if (IS_CONST == IS_CV) { - ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); } - } else /* if (IS_CONST == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(expr_ptr); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); + } + goto fetch_obj_r_no_object; + } while (0); + } - expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { - ZVAL_COPY_VALUE(&new_expr, expr_ptr); - expr_ptr = &new_expr; - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zval *retval; + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } } } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } + + if (UNEXPECTED(zobj->handlers->read_property == NULL)) { + zend_string *property_name; +fetch_obj_r_no_object: + property_name = zval_get_string(offset); + zend_error(E_NOTICE, "Trying to get property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + } + } + } while (0); + + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container; + zend_free_op free_op2; + zval *offset; + void **cache_slot = NULL; + + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zend_free_op free_op2; - zval *offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - zend_string *str; - zend_ulong hval; + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); -add_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index; + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; } } -str_index: - zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index: - zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto add_again; - } else if (Z_TYPE_P(offset) == IS_NULL) { - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval(Z_DVAL_P(offset)); - goto num_index; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - GET_OP2_UNDEF_CV(offset, BP_VAR_R); - str = ZSTR_EMPTY_ALLOC(); - goto str_index; + goto fetch_obj_is_no_object; + } while (0); + } + + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zval *retval; + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } + } + + if (UNEXPECTED(zobj->handlers->read_property == NULL)) { +fetch_obj_is_no_object: + ZVAL_NULL(EX_VAR(opline->result.var)); } else { - zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); + + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } } - zval_ptr_dtor_nogc(free_op2); + } while (0); + + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *container; + + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + zend_fetch_dimension_address_LIST_r(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *op1, *op2; + zend_string *op1_str, *op2_str, *str; + + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + zval_ptr_dtor_nogc(free_op1); + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + zval_ptr_dtor_nogc(free_op2); + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + zval_ptr_dtor_nogc(free_op2); + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); + } + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + op1_str = Z_STR_P(op1); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + op1_str = zend_string_copy(Z_STR_P(op1)); } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(op1, BP_VAR_R); } + op1_str = zval_get_string_func(op1); } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + op2_str = Z_STR_P(op2); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + op2_str = zend_string_copy(Z_STR_P(op2)); + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + op2_str = zval_get_string_func(op2); + } + do { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + zend_string_release(op1_str); + break; + } + } + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + zend_string_release(op2_str); + break; + } + } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_string_release(op1_str); + } + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_string_release(op2_str); + } + } while (0); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *array; - uint32_t size; USE_OPLINE + zval *function_name; + zend_free_op free_op1, free_op2; + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; - array = EX_VAR(opline->result.var); - if (IS_CONST != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; + SAVE_OPLINE(); + + object = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - if (IS_CONST != IS_UNUSED) { - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init(Z_ARRVAL_P(array), 0); + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } while (0); + } + + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + do { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + object = Z_REFVAL_P(object); + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + break; + } + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = GET_OP1_UNDEF_CV(object, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + } while (0); + } + + obj = Z_OBJ_P(object); + called_scope = obj->ce; + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + } else { + zend_object *orig_obj = obj; + + if (UNEXPECTED(obj->handlers->get_method == NULL)) { + zend_throw_error(NULL, "Object does not support method calls"); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); + } + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { + init_func_run_time_cache(&fbc->op_array); } } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + call_info = ZEND_CALL_NESTED_FUNCTION; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + obj = NULL; + } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; + GC_ADDREF(obj); /* For $this pointer */ + } + + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); + + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, called_scope, obj); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1, free_op2; + zval *op1, *op2, *result; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + do { + int result; + + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2)); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2))); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + zval_ptr_dtor_nogc(free_op2); + } else { + break; + } + } else { + break; + } + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); + } while (0); + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + result = EX_VAR(opline->result.var); + compare_function(result, op1, op2); + ZVAL_BOOL(result, Z_LVAL_P(result) == 0); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; zval *container; int result; zend_ulong hval; zval *offset; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -11916,7 +16404,7 @@ isset_again: } } str_index_prop: - value = zend_hash_find_ind(ht, str); + value = zend_hash_find_ex_ind(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: @@ -11956,7 +16444,7 @@ num_index_prop: result = (value == NULL || !i_zend_is_true(value)); } goto isset_dim_obj_exit; - } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { goto isset_dim_obj_array; @@ -11967,7 +16455,7 @@ num_index_prop: offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - if ((IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) { + if (((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) { if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ @@ -12013,32 +16501,32 @@ isset_not_found: isset_dim_obj_exit: zval_ptr_dtor_nogc(free_op2); - + zval_ptr_dtor_nogc(free_op1); ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1, free_op2; zval *container; int result; zval *offset; SAVE_OPLINE(); - container = EX_CONSTANT(opline->op1); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (IS_CONST == IS_CONST || - (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { goto isset_no_object; @@ -12060,20 +16548,20 @@ isset_no_object: } zval_ptr_dtor_nogc(free_op2); - + zval_ptr_dtor_nogc(free_op1); ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zend_free_op free_op1, free_op2; zval *container, *dim, *value; zend_long offset; - container = EX_CONSTANT(opline->op1); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_index_array: @@ -12084,14 +16572,14 @@ fetch_dim_r_index_array: } ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { SAVE_OPLINE(); - + zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { ZEND_VM_NEXT_OPCODE(); } - } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { goto fetch_dim_r_index_array; @@ -12102,7 +16590,7 @@ fetch_dim_r_index_array: fetch_dim_r_index_slow: SAVE_OPLINE(); zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim EXECUTE_DATA_CC); - + zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -12110,454 +16598,1949 @@ fetch_dim_r_index_undef: ZVAL_NULL(EX_VAR(opline->result.var)); SAVE_OPLINE(); zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) +{ + USE_OPLINE + zend_free_op free_op1; + zval *varname; + zval *retval; + + SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + retval = zend_fetch_static_property_address(varname, (IS_TMP_VAR|IS_VAR), opline->op2, IS_VAR, type EXECUTE_DATA_CC OPLINE_CC); + + if (UNEXPECTED(retval == NULL)) { + if (EG(exception)) { + zval_ptr_dtor_nogc(free_op1); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } else { + ZEND_ASSERT(type == BP_VAR_IS); + retval = &EG(uninitialized_zval); + } + } + + zval_ptr_dtor_nogc(free_op1); + + if (type == BP_VAR_R || type == BP_VAR_IS) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + } else { + ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } else { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; + zval *varname; + zend_string *name, *tmp_name; + zend_class_entry *ce; + zend_free_op free_op1; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - fast_long_add_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + if (IS_VAR == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + zend_std_unset_static_property(ce, name); + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; + zval *value; + int result; + zend_free_op free_op1; + zval *varname; + zend_string *name, *tmp_name; + zend_class_entry *ce; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + + if (IS_VAR == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + goto is_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + } + } else { + if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { + + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + goto is_static_prop_return; + } + } + + value = zend_std_get_static_property(ce, name, 1); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); + } + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); + +is_static_prop_return: + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; + zend_free_op free_op1; + zval *expr; + zend_bool result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + expr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; + + if (IS_VAR == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (EXPECTED(ce)) { + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + } + } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + zval_ptr_dtor_nogc(free_op1); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(expr, BP_VAR_R); + } + result = 0; + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - zval *op1, *op2, *result; + zend_free_op free_op1; + zval *varname; + zval *retval; + zend_string *name, *tmp_name; + HashTable *target_symbol_table; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - fast_long_sub_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); + retval = zend_hash_find_ex(target_symbol_table, name, (IS_TMP_VAR|IS_VAR) == IS_CONST); + if (retval == NULL) { + if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { + zval *result; + +fetch_this: + result = EX_VAR(opline->result.var); + switch (type) { + case BP_VAR_R: + if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) { + ZVAL_OBJ(result, Z_OBJ(EX(This))); + Z_ADDREF_P(result); + } else { + ZVAL_NULL(result); + zend_error(E_NOTICE,"Undefined variable: this"); + } + break; + case BP_VAR_IS: + if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) { + ZVAL_OBJ(result, Z_OBJ(EX(This))); + Z_ADDREF_P(result); + } else { + ZVAL_NULL(result); + } + break; + case BP_VAR_RW: + case BP_VAR_W: + ZVAL_UNDEF(result); + zend_throw_error(NULL, "Cannot re-assign $this"); + break; + case BP_VAR_UNSET: + ZVAL_UNDEF(result); + zend_throw_error(NULL, "Cannot unset $this"); + break; + EMPTY_SWITCH_DEFAULT_CASE() + } + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + switch (type) { + case BP_VAR_R: + case BP_VAR_UNSET: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + /* break missing intentionally */ + case BP_VAR_IS: + retval = &EG(uninitialized_zval); + break; + case BP_VAR_RW: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); + break; + case BP_VAR_W: + retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + break; + EMPTY_SWITCH_DEFAULT_CASE() + } + /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ + } else if (Z_TYPE_P(retval) == IS_INDIRECT) { + retval = Z_INDIRECT_P(retval); + if (Z_TYPE_P(retval) == IS_UNDEF) { + if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { + goto fetch_this; + } + switch (type) { + case BP_VAR_R: + case BP_VAR_UNSET: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + /* break missing intentionally */ + case BP_VAR_IS: + retval = &EG(uninitialized_zval); + break; + case BP_VAR_RW: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + /* break missing intentionally */ + case BP_VAR_W: + ZVAL_NULL(retval); + break; + EMPTY_SWITCH_DEFAULT_CASE() + } + } + } + + if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + zval_ptr_dtor_nogc(free_op1); + } + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + ZEND_ASSERT(retval != NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + } else { + ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } else { + ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - zval *op1, *op2, *result; + zend_free_op free_op1; + zval *varname; + zval *retval; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_LONG(result, Z_LVAL_P(op1) * Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + retval = zend_fetch_static_property_address(varname, (IS_TMP_VAR|IS_VAR), opline->op2, IS_UNUSED, type EXECUTE_DATA_CC OPLINE_CC); + + if (UNEXPECTED(retval == NULL)) { + if (EG(exception)) { + zval_ptr_dtor_nogc(free_op1); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } else { + ZEND_ASSERT(type == BP_VAR_IS); + retval = &EG(uninitialized_zval); + } + } + + zval_ptr_dtor_nogc(free_op1); + + if (type == BP_VAR_R || type == BP_VAR_IS) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + } else { + ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; - zend_long overflow; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); - Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; - ZEND_VM_NEXT_OPCODE(); + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } else { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; + zval *varname; + zend_string *name, *tmp_name; + HashTable *target_symbol_table; + zend_free_op free_op1; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); + zend_hash_del_ind(target_symbol_table, name); + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - int result; + zval *varname; + zend_string *name, *tmp_name; + zend_class_entry *ce; + zend_free_op free_op1; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + SAVE_OPLINE(); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + zend_std_unset_static_property(ce, name); + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *value; int result; + zend_free_op free_op1; + zval *varname; + zend_string *name, *tmp_name; + HashTable *target_symbol_table; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + + target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); + value = zend_hash_find_ex_ind(target_symbol_table, name, (IS_TMP_VAR|IS_VAR) == IS_CONST); + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); + + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *value; int result; + zend_free_op free_op1; + zval *varname; + zend_string *name, *tmp_name; + zend_class_entry *ce; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + + if (IS_UNUSED == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + goto is_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + } + } else { + if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { + + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + goto is_static_prop_return; + } + } + + value = zend_std_get_static_property(ce, name, 1); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); + } + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(free_op1); + +is_static_prop_return: + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - int result; + zend_free_op free_op1; + zval *expr; + zend_bool result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + SAVE_OPLINE(); + expr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (EXPECTED(ce)) { + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + } + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + zval_ptr_dtor_nogc(free_op1); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(expr, BP_VAR_R); + } + result = 0; + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - int result; + zend_free_op free_op1; + zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + fast_long_add_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2))); + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + add_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - int result; + zend_free_op free_op1; + zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + fast_long_sub_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2))); + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + sub_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zend_free_op free_op1; zval *op1, *op2; - int result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); + SAVE_OPLINE(); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + fast_div_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - int result; + zend_free_op free_op1; + zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { + SAVE_OPLINE(); + zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) { + /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */ + ZVAL_LONG(result, 0); + } else { + ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2)); + } + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + mod_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zend_free_op free_op1; zval *op1, *op2; - int result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) + && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + shift_left_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zend_free_op free_op1; zval *op1, *op2; - int result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) + && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + shift_right_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zend_free_op free_op1; zval *op1, *op2; - int result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + pow_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zend_free_op free_op1; zval *op1, *op2; - int result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + + if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + zval_ptr_dtor_nogc(free_op1); + } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + zval_ptr_dtor_nogc(free_op1); + + } + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + concat_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - int result; + zend_free_op free_op1; + zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + do { + int result; - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = ((double)Z_LVAL_P(op1) < Z_DVAL_P(op2)); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = (Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2))); + } else { + break; + } + } else { + break; + } + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); + } while (0); + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + result = EX_VAR(opline->result.var); + compare_function(result, op1, op2); + ZVAL_BOOL(result, Z_LVAL_P(result) < 0); + zval_ptr_dtor_nogc(free_op1); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - int result; + zend_free_op free_op1; + zval *op1, *op2, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + do { + int result; + + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = ((double)Z_LVAL_P(op1) <= Z_DVAL_P(op2)); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = (Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2))); + } else { + break; + } + } else { + break; + } + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); + } while (0); + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + result = EX_VAR(opline->result.var); + compare_function(result, op1, op2); + ZVAL_BOOL(result, Z_LVAL_P(result) <= 0); + zval_ptr_dtor_nogc(free_op1); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zend_free_op free_op1; zval *op1, *op2; - int result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + compare_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - int result; + zend_free_op free_op1; + zval *container, *dim, *value, *result; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + ZVAL_COPY_UNREF(result, value); + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R_slow(result, container, dim EXECUTE_DATA_CC); + } + } else { + result = EX_VAR(opline->result.var); + zend_fetch_dimension_address_read_R(result, container, dim, IS_CV EXECUTE_DATA_CC); + } - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - int result; + zend_free_op free_op1; + zval *container; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); + + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - int result; + zend_free_op free_op1; + zval *container; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + zval *offset; + void **cache_slot = NULL; + + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + offset = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); + } + goto fetch_obj_r_no_object; + } while (0); + } + + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zval *retval; + + if (IS_CV == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } + } + } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); + } + + if (UNEXPECTED(zobj->handlers->read_property == NULL)) { + zend_string *property_name; +fetch_obj_r_no_object: + property_name = zval_get_string(offset); + zend_error(E_NOTICE, "Trying to get property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + } + } + } while (0); + + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - int result; + zend_free_op free_op1; + zval *container; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + zval *offset; + void **cache_slot = NULL; - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + goto fetch_obj_is_no_object; + } while (0); + } + + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zval *retval; + + if (IS_CV == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } + } + + if (UNEXPECTED(zobj->handlers->read_property == NULL)) { +fetch_obj_is_no_object: + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } + } while (0); + + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - int result; + zend_free_op free_op1; + zval *container; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + zend_fetch_dimension_address_LIST_r(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC) EXECUTE_DATA_CC); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zend_free_op free_op1; zval *op1, *op2; - int result; + zend_string *op1_str, *op2_str, *str; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + zval_ptr_dtor_nogc(free_op1); + } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + zval_ptr_dtor_nogc(free_op1); + + } + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + op1_str = Z_STR_P(op1); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + op1_str = zend_string_copy(Z_STR_P(op1)); + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + op1_str = zval_get_string_func(op1); + } + if (IS_CV == IS_CONST) { + op2_str = Z_STR_P(op2); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + op2_str = zend_string_copy(Z_STR_P(op2)); + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + op2_str = zval_get_string_func(op2); + } + do { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + zend_string_release(op1_str); + break; + } + } + if (IS_CV != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + zend_string_release(op2_str); + break; + } + } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_string_release(op1_str); + } + if (IS_CV != IS_CONST) { + zend_string_release(op2_str); + } + } while (0); + zval_ptr_dtor_nogc(free_op1); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - int result; + zval *function_name; + zend_free_op free_op1; + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + SAVE_OPLINE(); + + object = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + + if (IS_CV != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); + + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } while (0); + } + + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + do { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + object = Z_REFVAL_P(object); + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + break; + } + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = GET_OP1_UNDEF_CV(object, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); + + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + } while (0); + } + + obj = Z_OBJ_P(object); + called_scope = obj->ce; + + if (IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + } else { + zend_object *orig_obj = obj; + + if (UNEXPECTED(obj->handlers->get_method == NULL)) { + zend_throw_error(NULL, "Object does not support method calls"); + + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); + } + + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + if (IS_CV == IS_CONST && + EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { + init_func_run_time_cache(&fbc->op_array); + } + } + + call_info = ZEND_CALL_NESTED_FUNCTION; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + obj = NULL; + } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; + GC_ADDREF(obj); /* For $this pointer */ + } + + zval_ptr_dtor_nogc(free_op1); + + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, called_scope, obj); + call->prev_execute_data = EX(call); + EX(call) = call; - ZVAL_BOOL(EX_VAR(opline->result.var), result); ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zend_free_op free_op1; + zval *op1, *op2, *result; + + op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + do { + int result; + + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2)); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2))); + } else { + break; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + + } else { + break; + } + } else { + break; + } + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); + } while (0); + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + result = EX_VAR(opline->result.var); + compare_function(result, op1, op2); + ZVAL_BOOL(result, Z_LVAL_P(result) == 0); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container; int result; + zend_ulong hval; + zval *offset; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + offset = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + zval *value; + zend_string *str; + +isset_dim_obj_array: + ht = Z_ARRVAL_P(container); +isset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_CV != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_prop; + } + } +str_index_prop: + value = zend_hash_find_ex_ind(ht, str, IS_CV == IS_CONST); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_prop: + value = zend_hash_index_find(ht, hval); + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + offset = Z_REFVAL_P(offset); + goto isset_again; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index_prop; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index_prop; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_prop; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_prop; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + hval = Z_RES_HANDLE_P(offset); + goto num_index_prop; + } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); + str = ZSTR_EMPTY_ALLOC(); + goto str_index_prop; + } else { + zend_error(E_WARNING, "Illegal offset type in isset or empty"); + goto isset_not_found; + } + + if (opline->extended_value & ZEND_ISSET) { + /* > IS_NULL means not IS_UNDEF and not IS_NULL */ + result = value != NULL && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = (value == NULL || !i_zend_is_true(value)); + } + goto isset_dim_obj_exit; + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto isset_dim_obj_array; + } + } + + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); + } + + if (((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) { + if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) { + result = + ((opline->extended_value & ZEND_ISSET) == 0) ^ + Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0); + } else { + zend_error(E_NOTICE, "Trying to check element of non-array"); + goto isset_not_found; + } + } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */ + zend_long lval; + + if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + lval = Z_LVAL_P(offset); +isset_str_offset: + if (UNEXPECTED(lval < 0)) { /* Handle negative offset */ + lval += (zend_long)Z_STRLEN_P(container); + } + if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) { + if (opline->extended_value & ZEND_ISSET) { + result = 1; + } else { + result = (Z_STRVAL_P(container)[lval] == '0'); + } + } else { + goto isset_not_found; + } + } else { + if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(offset); + } + if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ + || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ + && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { + lval = zval_get_long(offset); + goto isset_str_offset; + } + goto isset_not_found; + } + } else { +isset_not_found: + result = ((opline->extended_value & ZEND_ISSET) == 0); + } + +isset_dim_obj_exit: + + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zend_free_op free_op1; + zval *container; int result; + zval *offset; - op1 = EX_CONSTANT(opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + goto isset_no_object; + } + } else { + goto isset_no_object; + } + } + if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { + zend_string *property_name = zval_get_string(offset); + zend_error(E_NOTICE, "Trying to check property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); +isset_no_object: + result = ((opline->extended_value & ZEND_ISSET) == 0); + } else { + result = + ((opline->extended_value & ZEND_ISSET) == 0) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + } + + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container, *dim, *value; + zend_long offset; + + container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + offset = zval_get_long(dim); + } + ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); + if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -12612,7 +18595,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HA retval_ptr = Z_REFVAL_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { Z_ADDREF_P(retval_ptr); @@ -12650,7 +18633,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER ZVAL_NEW_REF(EX(return_value), retval_ptr); if (IS_TMP_VAR == IS_CONST) { - if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr); + Z_TRY_ADDREF_P(retval_ptr); } } break; @@ -12710,7 +18693,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_TMP_HAND retval = Z_REFVAL_P(retval); ZVAL_COPY_VALUE(&generator->retval, retval); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(retval)) { Z_ADDREF_P(retval); @@ -12758,7 +18741,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OP zend_exception_save(); if (IS_TMP_VAR != IS_TMP_VAR) { - if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value); + Z_TRY_ADDREF_P(value); } zend_throw_exception_object(value); @@ -12897,15 +18880,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPC if (opline->extended_value == IS_ARRAY) { if (Z_TYPE_P(expr) != IS_OBJECT) { - ZVAL_NEW_ARR(result); - zend_hash_init(Z_ARRVAL_P(result), 8, NULL, ZVAL_PTR_DTOR, 0); if (Z_TYPE_P(expr) != IS_NULL) { + ZVAL_ARR(result, zend_new_array(8)); expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr); if (IS_TMP_VAR == IS_CONST) { if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr); } else { if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); } + } else { + ZVAL_EMPTY_ARRAY(result); } } else { ZVAL_COPY_VALUE(result, expr); @@ -12962,7 +18946,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZE if (Z_OBJ_P(array_ptr)->properties && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties)--; + GC_DELREF(Z_OBJ_P(array_ptr)->properties); } Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); } @@ -13066,6 +19050,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(Z } Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0); + if (IS_TMP_VAR == IS_VAR) { + + } ZEND_VM_NEXT_OPCODE(); } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { if (!Z_OBJCE_P(array_ptr)->get_iterator) { @@ -13083,12 +19070,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(Z if (Z_OBJ_P(array_ptr)->properties && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties)--; + GC_DELREF(Z_OBJ_P(array_ptr)->properties); } Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); } Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0); + if (IS_TMP_VAR == IS_VAR) { + + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { zend_class_entry *ce = Z_OBJCE_P(array_ptr); @@ -13214,7 +19204,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_ } else if (IS_TMP_VAR == IS_VAR && ref) { zend_reference *r = Z_REF_P(ref); - if (UNEXPECTED(--GC_REFCOUNT(r) == 0)) { + if (UNEXPECTED(GC_DELREF(r) == 0)) { efree_size(r, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(result)) { Z_ADDREF_P(result); @@ -13255,7 +19245,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND } else if (IS_TMP_VAR == IS_VAR && ref) { zend_reference *r = Z_REF_P(ref); - if (UNEXPECTED(--GC_REFCOUNT(r) == 0)) { + if (UNEXPECTED(GC_DELREF(r) == 0)) { efree_size(r, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(result)) { Z_ADDREF_P(result); @@ -13421,26 +19411,37 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_TMP_HANDLER(ZE int result = 0; zend_free_op free_op1; - SAVE_OPLINE(); value = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) { - if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) { - const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value)); - - if (EXPECTED(type_name != NULL)) { - result = 1; - } - } else { + if ((1 << (uint32_t)Z_TYPE_P(value) & opline->extended_value)) { +type_check_resource: + if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE) + || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) { result = 1; } - } else if (UNEXPECTED(opline->extended_value == _IS_BOOL) && - EXPECTED(Z_TYPE_P(value) == IS_TRUE || Z_TYPE_P(value) == IS_FALSE)) { - result = 1; + } else if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + if ((1 << (uint32_t)Z_TYPE_P(value) & opline->extended_value)) { + goto type_check_resource; + } + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + result = ((1 << IS_NULL) & opline->extended_value) != 0; + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(value, BP_VAR_R); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -13452,7 +19453,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HA SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@ -13470,7 +19471,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONS SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@ -13482,148 +19483,48 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONS static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zend_free_op free_op1; - - SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = NULL; - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { if (IS_CONST == IS_UNUSED) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use [] for reading"); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(free_op1); + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if (IS_TMP_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - offset = EX_CONSTANT(opline->op2); - - if (IS_TMP_VAR == IS_CONST || - (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_r_no_object; - } - } else { - goto fetch_obj_r_no_object; - } - } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zval *retval; - - if (IS_CONST == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } - } - - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { - zend_string *property_name; -fetch_obj_r_no_object: - property_name = zval_get_string(offset); - zend_error(E_NOTICE, "Trying to get property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - } - } - } while (0); - - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1; - zval *property; - - SAVE_OPLINE(); - container = NULL; - - if (IS_TMP_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); - + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - property = EX_CONSTANT(opline->op2); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -13637,10 +19538,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_CONST_HANDLE /* op1 and result are the same */ rope = (zend_string**)EX_VAR(opline->op1.var); if (IS_CONST == IS_CONST) { - var = EX_CONSTANT(opline->op2); - rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); + var = RT_CONSTANT(opline, opline->op2); + rope[opline->extended_value] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); + } } else { - var = EX_CONSTANT(opline->op2); + var = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { if (IS_CONST == IS_CV) { rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); @@ -13652,7 +19556,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_CONST_HANDLE if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { GET_OP2_UNDEF_CV(var, BP_VAR_R); } - rope[opline->extended_value] = _zval_get_string_func(var); + rope[opline->extended_value] = zval_get_string_func(var); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -13672,10 +19576,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CONST_HANDLE rope = (zend_string**)EX_VAR(opline->op1.var); if (IS_CONST == IS_CONST) { - var = EX_CONSTANT(opline->op2); - rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); + var = RT_CONSTANT(opline, opline->op2); + rope[opline->extended_value] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); + } } else { - var = EX_CONSTANT(opline->op2); + var = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { if (IS_CONST == IS_CV) { rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); @@ -13687,7 +19594,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CONST_HANDLE if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { GET_OP2_UNDEF_CV(var, BP_VAR_R); } - rope[opline->extended_value] = _zval_get_string_func(var); + rope[opline->extended_value] = zval_get_string_func(var); if (UNEXPECTED(EG(exception))) { for (i = 0; i <= opline->extended_value; i++) { @@ -13732,20 +19639,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CON if (IS_TMP_VAR == IS_TMP_VAR) { /* pass */ } else if (IS_TMP_VAR == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else if (IS_TMP_VAR == IS_CV) { ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else /* if (IS_TMP_VAR == IS_VAR) */ { if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { zend_refcounted *ref = Z_COUNTED_P(expr_ptr); expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; efree_size(ref, sizeof(zend_reference)); @@ -13758,7 +19661,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CON if (IS_CONST != IS_UNUSED) { - zval *offset = EX_CONSTANT(opline->op2); + zval *offset = RT_CONSTANT(opline, opline->op2); zend_string *str; zend_ulong hval; @@ -13797,13 +19700,13 @@ num_index: goto str_index; } else { zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -13818,20 +19721,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_CONST_HAND array = EX_VAR(opline->result.var); if (IS_TMP_VAR != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - - if (IS_TMP_VAR != IS_UNUSED) { + ZVAL_ARR(array, zend_new_array(size)); /* Explicitly initialize array as not-packed if flag is set */ if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init(Z_ARRVAL_P(array), 0); } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -13919,7 +19818,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(Z /* Set the new yielded key */ if (IS_CONST != IS_UNUSED) { - zval *key = EX_CONSTANT(opline->op2); + zval *key = RT_CONSTANT(opline, opline->op2); /* Consts, temporary variables and references need copying */ if (IS_CONST == IS_CONST) { @@ -13975,7 +19874,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLE USE_OPLINE zend_free_op free_op1; zval *op1; - HashTable *ht = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); + HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); int result; SAVE_OPLINE(); @@ -14010,6 +19909,259 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use temporary expression in write context"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use [] for reading"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + /* Behave like FETCH_OBJ_W */ + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use temporary expression in write context"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zend_string **rope; + zval *var; + + /* op1 and result are the same */ + rope = (zend_string**)EX_VAR(opline->op1.var); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + var = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + rope[opline->extended_value] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); + } + } else { + var = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV) { + rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); + } else { + rope[opline->extended_value] = Z_STR_P(var); + } + } else { + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(var, BP_VAR_R); + } + rope[opline->extended_value] = zval_get_string_func(var); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zend_string **rope; + zval *var, *ret; + uint32_t i; + size_t len = 0; + char *target; + + rope = (zend_string**)EX_VAR(opline->op1.var); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + var = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + rope[opline->extended_value] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); + } + } else { + var = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV) { + rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); + } else { + rope[opline->extended_value] = Z_STR_P(var); + } + } else { + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(var, BP_VAR_R); + } + rope[opline->extended_value] = zval_get_string_func(var); + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(EG(exception))) { + for (i = 0; i <= opline->extended_value; i++) { + zend_string_release(rope[i]); + } + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } + } + for (i = 0; i <= opline->extended_value; i++) { + len += ZSTR_LEN(rope[i]); + } + ret = EX_VAR(opline->result.var); + ZVAL_STR(ret, zend_string_alloc(len, 0)); + target = Z_STRVAL_P(ret); + for (i = 0; i <= opline->extended_value; i++) { + memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i])); + target += ZSTR_LEN(rope[i]); + zend_string_release(rope[i]); + } + *target = '\0'; + + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *expr_ptr, new_expr; + + SAVE_OPLINE(); + if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && + UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { + expr_ptr = NULL; + ZVAL_MAKE_REF(expr_ptr); + Z_ADDREF_P(expr_ptr); + + } else { + expr_ptr = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_TMP_VAR) { + /* pass */ + } else if (IS_TMP_VAR == IS_CONST) { + Z_TRY_ADDREF_P(expr_ptr); + } else if (IS_TMP_VAR == IS_CV) { + ZVAL_DEREF(expr_ptr); + Z_TRY_ADDREF_P(expr_ptr); + } else /* if (IS_TMP_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(expr_ptr); + + expr_ptr = Z_REFVAL_P(expr_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + ZVAL_COPY_VALUE(&new_expr, expr_ptr); + expr_ptr = &new_expr; + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } + } + } + } + + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zend_free_op free_op2; + zval *offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + zend_string *str; + zend_ulong hval; + +add_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index; + } + } +str_index: + zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index: + zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto add_again; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index; + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else { + zend_error(E_WARNING, "Illegal offset type"); + zval_ptr_dtor_nogc(expr_ptr); + } + zval_ptr_dtor_nogc(free_op2); + } else { + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + zval_ptr_dtor_nogc(expr_ptr); + } + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zval *array; + uint32_t size; + USE_OPLINE + + array = EX_VAR(opline->result.var); + if (IS_TMP_VAR != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init(Z_ARRVAL_P(array), 0); + } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); + } +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -14182,42 +20334,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEN ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -14357,40 +20473,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zend_free_op free_op1; - - SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = NULL; - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { if (IS_UNUSED == IS_UNUSED) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use [] for reading"); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, NULL, IS_UNUSED EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(free_op1); + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -14461,20 +20565,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNU if (IS_TMP_VAR == IS_TMP_VAR) { /* pass */ } else if (IS_TMP_VAR == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else if (IS_TMP_VAR == IS_CV) { ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else /* if (IS_TMP_VAR == IS_VAR) */ { if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { zend_refcounted *ref = Z_COUNTED_P(expr_ptr); expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; efree_size(ref, sizeof(zend_reference)); @@ -14526,13 +20626,13 @@ num_index: goto str_index; } else { zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -14547,20 +20647,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HAN array = EX_VAR(opline->result.var); if (IS_TMP_VAR != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - - if (IS_TMP_VAR != IS_UNUSED) { + ZVAL_ARR(array, zend_new_array(size)); /* Explicitly initialize array as not-packed if flag is set */ if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init(Z_ARRVAL_P(array), 0); } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -14795,187 +20891,51 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_TMP_UNUSED_HANDL ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zend_free_op free_op1; - - SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = NULL; - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { if (IS_CV == IS_UNUSED) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use [] for reading"); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(free_op1); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if (IS_TMP_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - - if (IS_TMP_VAR == IS_CONST || - (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_r_no_object; - } - } else { - goto fetch_obj_r_no_object; - } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zval *retval; - - if (IS_CV == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } - } - - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { - zend_string *property_name; -fetch_obj_r_no_object: - property_name = zval_get_string(offset); - zend_error(E_NOTICE, "Trying to get property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - } - } - } while (0); - - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1; - zval *property; - - SAVE_OPLINE(); - container = NULL; - - if (IS_TMP_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); - + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -14990,7 +20950,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_CV_HANDLER(Z rope = (zend_string**)EX_VAR(opline->op1.var); if (IS_CV == IS_CONST) { var = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); + rope[opline->extended_value] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); + } } else { var = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { @@ -15004,7 +20967,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_CV_HANDLER(Z if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { GET_OP2_UNDEF_CV(var, BP_VAR_R); } - rope[opline->extended_value] = _zval_get_string_func(var); + rope[opline->extended_value] = zval_get_string_func(var); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -15025,7 +20988,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CV_HANDLER(Z rope = (zend_string**)EX_VAR(opline->op1.var); if (IS_CV == IS_CONST) { var = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); + rope[opline->extended_value] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); + } } else { var = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { @@ -15039,7 +21005,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CV_HANDLER(Z if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { GET_OP2_UNDEF_CV(var, BP_VAR_R); } - rope[opline->extended_value] = _zval_get_string_func(var); + rope[opline->extended_value] = zval_get_string_func(var); if (UNEXPECTED(EG(exception))) { for (i = 0; i <= opline->extended_value; i++) { @@ -15084,20 +21050,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_ if (IS_TMP_VAR == IS_TMP_VAR) { /* pass */ } else if (IS_TMP_VAR == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else if (IS_TMP_VAR == IS_CV) { ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else /* if (IS_TMP_VAR == IS_VAR) */ { if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { zend_refcounted *ref = Z_COUNTED_P(expr_ptr); expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; efree_size(ref, sizeof(zend_reference)); @@ -15149,13 +21111,13 @@ num_index: goto str_index; } else { zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -15170,20 +21132,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER array = EX_VAR(opline->result.var); if (IS_TMP_VAR != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - - if (IS_TMP_VAR != IS_UNUSED) { + ZVAL_ARR(array, zend_new_array(size)); /* Explicitly initialize array as not-packed if flag is set */ if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init(Z_ARRVAL_P(array), 0); } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -15353,362 +21311,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_LEXICAL_SPEC_TMP_CV_HANDL ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - zend_free_op free_op1, free_op2; - - SAVE_OPLINE(); - - if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { - zend_throw_error(NULL, "Cannot use temporary expression in write context"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - container = NULL; - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - zval_ptr_dtor_nogc(free_op2); - - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_throw_error(NULL, "Cannot use [] for reading"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - container = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - zend_free_op free_op2; - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if (IS_TMP_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - if (IS_TMP_VAR == IS_CONST || - (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_r_no_object; - } - } else { - goto fetch_obj_r_no_object; - } - } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zval *retval; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } - } - - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { - zend_string *property_name; -fetch_obj_r_no_object: - property_name = zval_get_string(offset); - zend_error(E_NOTICE, "Trying to get property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - } - } - } while (0); - - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - - if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1, free_op2; - zval *property; - - SAVE_OPLINE(); - container = NULL; - - if (IS_TMP_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { - zend_throw_error(NULL, "Cannot use temporary expression in write context"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - zval_ptr_dtor_nogc(free_op2); - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zend_string **rope; - zval *var; - - /* op1 and result are the same */ - rope = (zend_string**)EX_VAR(opline->op1.var); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - var = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); - } else { - var = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); - } else { - rope[opline->extended_value] = Z_STR_P(var); - } - } else { - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(var, BP_VAR_R); - } - rope[opline->extended_value] = _zval_get_string_func(var); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zend_string **rope; - zval *var, *ret; - uint32_t i; - size_t len = 0; - char *target; - - rope = (zend_string**)EX_VAR(opline->op1.var); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - var = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); - } else { - var = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); - } else { - rope[opline->extended_value] = Z_STR_P(var); - } - } else { - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(var, BP_VAR_R); - } - rope[opline->extended_value] = _zval_get_string_func(var); - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(EG(exception))) { - for (i = 0; i <= opline->extended_value; i++) { - zend_string_release(rope[i]); - } - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } - } - for (i = 0; i <= opline->extended_value; i++) { - len += ZSTR_LEN(rope[i]); - } - ret = EX_VAR(opline->result.var); - ZVAL_STR(ret, zend_string_alloc(len, 0)); - target = Z_STRVAL_P(ret); - for (i = 0; i <= opline->extended_value; i++) { - memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i])); - target += ZSTR_LEN(rope[i]); - zend_string_release(rope[i]); - } - *target = '\0'; - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *expr_ptr, new_expr; - - SAVE_OPLINE(); - if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && - UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = NULL; - ZVAL_MAKE_REF(expr_ptr); - Z_ADDREF_P(expr_ptr); - - } else { - expr_ptr = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_TMP_VAR) { - /* pass */ - } else if (IS_TMP_VAR == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } else if (IS_TMP_VAR == IS_CV) { - ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } else /* if (IS_TMP_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(expr_ptr); - - expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { - ZVAL_COPY_VALUE(&new_expr, expr_ptr); - expr_ptr = &new_expr; - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } - } - } - - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zend_free_op free_op2; - zval *offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - zend_string *str; - zend_ulong hval; - -add_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index; - } - } -str_index: - zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index: - zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto add_again; - } else if (Z_TYPE_P(offset) == IS_NULL) { - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval(Z_DVAL_P(offset)); - goto num_index; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - GET_OP2_UNDEF_CV(offset, BP_VAR_R); - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else { - zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); - } - zval_ptr_dtor_nogc(free_op2); - } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); - } - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zval *array; - uint32_t size; - USE_OPLINE - - array = EX_VAR(opline->result.var); - if (IS_TMP_VAR != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - - if (IS_TMP_VAR != IS_UNUSED) { - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init(Z_ARRVAL_P(array), 0); - } - } - - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -15737,7 +21339,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_RETVAL_UNUSED var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); increment_function(var_ptr); @@ -15777,7 +21378,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_RETVAL_USED_H var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); increment_function(var_ptr); @@ -15817,7 +21417,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_RETVAL_UNUSED var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); decrement_function(var_ptr); @@ -15857,7 +21456,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_RETVAL_USED_H var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); decrement_function(var_ptr); @@ -15893,8 +21491,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - zval_opt_copy_ctor(var_ptr); + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); increment_function(var_ptr); @@ -15926,8 +21523,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - zval_opt_copy_ctor(var_ptr); + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); decrement_function(var_ptr); @@ -15987,7 +21583,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HA retval_ptr = Z_REFVAL_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { Z_ADDREF_P(retval_ptr); @@ -16025,7 +21621,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER ZVAL_NEW_REF(EX(return_value), retval_ptr); if (IS_VAR == IS_CONST) { - if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr); + Z_TRY_ADDREF_P(retval_ptr); } } break; @@ -16086,7 +21682,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_VAR_HAND retval = Z_REFVAL_P(retval); ZVAL_COPY_VALUE(&generator->retval, retval); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(retval)) { Z_ADDREF_P(retval); @@ -16134,7 +21730,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OP zend_exception_save(); if (IS_VAR != IS_TMP_VAR) { - if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value); + Z_TRY_ADDREF_P(value); } zend_throw_exception_object(value); @@ -16169,7 +21765,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_ varptr = Z_REFVAL_P(varptr); ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(arg)) { Z_ADDREF_P(arg); @@ -16346,7 +21942,7 @@ send_var_by_ref: varptr = Z_REFVAL_P(varptr); ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(arg)) { Z_ADDREF_P(arg); @@ -16395,7 +21991,7 @@ send_var_by_ref: varptr = Z_REFVAL_P(varptr); ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(arg)) { Z_ADDREF_P(arg); @@ -16442,15 +22038,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCO SAVE_OPLINE(); if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -16549,15 +22145,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPC if (opline->extended_value == IS_ARRAY) { if (Z_TYPE_P(expr) != IS_OBJECT) { - ZVAL_NEW_ARR(result); - zend_hash_init(Z_ARRVAL_P(result), 8, NULL, ZVAL_PTR_DTOR, 0); if (Z_TYPE_P(expr) != IS_NULL) { + ZVAL_ARR(result, zend_new_array(8)); expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr); if (IS_VAR == IS_CONST) { if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr); } else { if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); } + } else { + ZVAL_EMPTY_ARRAY(result); } } else { ZVAL_COPY_VALUE(result, expr); @@ -16615,7 +22212,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZE if (Z_OBJ_P(array_ptr)->properties && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties)--; + GC_DELREF(Z_OBJ_P(array_ptr)->properties); } Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); } @@ -16720,7 +22317,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(Z } Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + if (IS_VAR == IS_VAR) { + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + } ZEND_VM_NEXT_OPCODE(); } else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { if (!Z_OBJCE_P(array_ptr)->get_iterator) { @@ -16738,13 +22337,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(Z if (Z_OBJ_P(array_ptr)->properties && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties)--; + GC_DELREF(Z_OBJ_P(array_ptr)->properties); } Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); } Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + if (IS_VAR == IS_VAR) { + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { zend_class_entry *ce = Z_OBJCE_P(array_ptr); @@ -16977,7 +22578,7 @@ fe_fetch_r_exit: ZVAL_COPY_VALUE_EX(res, value, gc, value_type); if (EXPECTED((value_type & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0)) { - GC_REFCOUNT(gc)++; + GC_ADDREF(gc); } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -17146,7 +22747,7 @@ fe_fetch_w_exit: zend_reference *ref; ref = Z_REF_P(value); - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); zval_ptr_dtor(variable_ptr); ZVAL_REF(variable_ptr, ref); } @@ -17194,7 +22795,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_ } else if (IS_VAR == IS_VAR && ref) { zend_reference *r = Z_REF_P(ref); - if (UNEXPECTED(--GC_REFCOUNT(r) == 0)) { + if (UNEXPECTED(GC_DELREF(r) == 0)) { efree_size(r, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(result)) { Z_ADDREF_P(result); @@ -17235,7 +22836,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND } else if (IS_VAR == IS_VAR && ref) { zend_reference *r = Z_REF_P(ref); - if (UNEXPECTED(--GC_REFCOUNT(r) == 0)) { + if (UNEXPECTED(GC_DELREF(r) == 0)) { efree_size(r, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(result)) { Z_ADDREF_P(result); @@ -17403,26 +23004,37 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_VAR_HANDLER(ZE int result = 0; zend_free_op free_op1; - SAVE_OPLINE(); - value = _get_zval_ptr_var_deref(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) { - if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) { - const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value)); - - if (EXPECTED(type_name != NULL)) { - result = 1; - } - } else { + value = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if ((1 << (uint32_t)Z_TYPE_P(value) & opline->extended_value)) { +type_check_resource: + if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE) + || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) { result = 1; } - } else if (UNEXPECTED(opline->extended_value == _IS_BOOL) && - EXPECTED(Z_TYPE_P(value) == IS_TRUE || Z_TYPE_P(value) == IS_FALSE)) { - result = 1; + } else if ((IS_VAR & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + if ((1 << (uint32_t)Z_TYPE_P(value) & opline->extended_value)) { + goto type_check_resource; + } + } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + result = ((1 << IS_NULL) & opline->extended_value) != 0; + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(value, BP_VAR_R); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + if (IS_VAR & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SIMPLE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -17508,7 +23120,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HA SAVE_OPLINE(); op1 = _get_zval_ptr_var_deref(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@ -17526,7 +23138,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONS SAVE_OPLINE(); op1 = _get_zval_ptr_var_deref(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@ -17551,10 +23163,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); do { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -17578,7 +23190,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); binary_op(zptr, zptr, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -17611,6 +23222,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP assign_dim_op_array: SEPARATE_ARRAY(container); assign_dim_op_new_array: + dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_UNUSED) { var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { @@ -17618,8 +23230,6 @@ assign_dim_op_new_array: goto assign_dim_op_ret_null; } } else { - dim = EX_CONSTANT(opline->op2); - if (IS_CONST == IS_CONST) { var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); } else { @@ -17629,10 +23239,9 @@ assign_dim_op_new_array: goto assign_dim_op_ret_null; } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); binary_op(var_ptr, var_ptr, value); @@ -17648,15 +23257,14 @@ assign_dim_op_new_array: } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(container, zend_new_array(8)); goto assign_dim_op_new_array; } - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC); } else { if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { @@ -17678,7 +23286,7 @@ assign_dim_op_ret_null: ZVAL_NULL(EX_VAR(opline->result.var)); } } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); } } @@ -17695,7 +23303,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper zval *value; SAVE_OPLINE(); - value = EX_CONSTANT(opline->op2); + value = RT_CONSTANT(opline, opline->op2); var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { @@ -17704,7 +23312,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper } } else { ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); binary_op(var_ptr, var_ptr, value); @@ -17972,7 +23579,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -18004,7 +23611,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); if (inc) { increment_function(zptr); @@ -18050,7 +23656,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -18080,8 +23686,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } else { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); - zval_opt_copy_ctor(zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); if (inc) { increment_function(zptr); } else { @@ -18117,7 +23722,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HAN SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, RT_CONSTANT(opline, opline->op2), IS_CONST EXECUTE_DATA_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -18135,7 +23740,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HA SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); + zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, RT_CONSTANT(opline, opline->op2), IS_CONST EXECUTE_DATA_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -18147,40 +23752,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zend_free_op free_op1; - - SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { if (IS_CONST == IS_UNUSED) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use [] for reading"); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(free_op1); + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -18192,7 +23785,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); + zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, RT_CONSTANT(opline, opline->op2), IS_CONST EXECUTE_DATA_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -18201,79 +23794,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - offset = EX_CONSTANT(opline->op2); - - if (IS_VAR == IS_CONST || - (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_r_no_object; - } - } else { - goto fetch_obj_r_no_object; - } - } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zval *retval; - - if (IS_CONST == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } - } - - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { - zend_string *property_name; -fetch_obj_r_no_object: - property_name = zval_get_string(offset); - zend_error(E_NOTICE, "Trying to get property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - } - } - } while (0); - - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -18288,7 +23808,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HAN ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -18311,7 +23831,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HA if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -18324,36 +23844,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HA static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1; - zval *property; - - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - property = EX_CONSTANT(opline->op2); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -18370,7 +23875,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); @@ -18381,6 +23886,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *retval, *container, *dim; + + SAVE_OPLINE(); + retval = EX_VAR(opline->result.var); + container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + dim = RT_CONSTANT(opline, opline->op2); + + if (IS_VAR == IS_VAR + && Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT + && UNEXPECTED(!Z_ISREF_P(container)) + ) { + zend_error(E_NOTICE, "Attempting to set reference to non referenceable value"); + zend_fetch_dimension_address_LIST_r(retval, container, dim EXECUTE_DATA_CC); + } else { + zend_fetch_dimension_address_LIST_w(retval, container, dim EXECUTE_DATA_CC); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -18394,8 +23923,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); - value = EX_CONSTANT((opline+1)->op1); + property = RT_CONSTANT(opline, opline->op2); + value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { do { @@ -18409,7 +23938,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -18441,11 +23970,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D if (IS_CONST == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -18459,11 +23988,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -18482,24 +24011,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CONST == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -18552,7 +24077,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -18567,7 +24092,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -18599,11 +24124,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D if (IS_CONST == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -18617,11 +24142,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -18640,24 +24165,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_TMP_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -18710,7 +24231,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -18725,7 +24246,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -18757,11 +24278,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D if (IS_CONST == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -18775,11 +24296,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -18798,24 +24319,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -18868,7 +24385,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -18883,7 +24400,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -18915,11 +24432,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D if (IS_CONST == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -18933,11 +24450,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -18956,24 +24473,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CV == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CV == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -19036,7 +24549,7 @@ try_assign_dim_array: goto assign_dim_error; } } else { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { @@ -19046,7 +24559,7 @@ try_assign_dim_array: goto assign_dim_error; } } - value = EX_CONSTANT((opline+1)->op1); + value = RT_CONSTANT((opline+1), (opline+1)->op1); value = zend_assign_to_variable(variable_ptr, value, IS_CONST); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -19059,8 +24572,8 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = EX_CONSTANT(opline->op2); - value = EX_CONSTANT((opline+1)->op1); + dim = RT_CONSTANT(opline, opline->op2); + value = RT_CONSTANT((opline+1), (opline+1)->op1); zend_assign_to_object_dim(object_ptr, dim, value); @@ -19076,20 +24589,19 @@ try_assign_dim_array: UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = EX_CONSTANT(opline->op2); - value = EX_CONSTANT((opline+1)->op1); + dim = RT_CONSTANT(opline, opline->op2); + value = RT_CONSTANT((opline+1), (opline+1)->op1); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); assign_dim_error: if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -19128,7 +24640,7 @@ try_assign_dim_array: goto assign_dim_error; } } else { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { @@ -19151,7 +24663,7 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_object_dim(object_ptr, dim, value); @@ -19169,20 +24681,19 @@ try_assign_dim_array: UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); zval_ptr_dtor_nogc(free_op_data); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); assign_dim_error: zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -19221,7 +24732,7 @@ try_assign_dim_array: goto assign_dim_error; } } else { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { @@ -19244,7 +24755,7 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_object_dim(object_ptr, dim, value); @@ -19262,20 +24773,19 @@ try_assign_dim_array: UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); zval_ptr_dtor_nogc(free_op_data); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); assign_dim_error: zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -19314,7 +24824,7 @@ try_assign_dim_array: goto assign_dim_error; } } else { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { @@ -19337,7 +24847,7 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); zend_assign_to_object_dim(object_ptr, dim, value); @@ -19354,20 +24864,19 @@ try_assign_dim_array: UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); assign_dim_error: if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -19391,7 +24900,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_U zval *variable_ptr; SAVE_OPLINE(); - value = EX_CONSTANT(opline->op2); + value = RT_CONSTANT(opline, opline->op2); variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { @@ -19419,7 +24928,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_U zval *variable_ptr; SAVE_OPLINE(); - value = EX_CONSTANT(opline->op2); + value = RT_CONSTANT(opline, opline->op2); variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { @@ -19452,14 +24961,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -19474,16 +24983,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR == IS_CONST && IS_CONST == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { /* nothing to do */ } else if (IS_VAR != IS_CONST && IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); } else if (IS_CONST != IS_UNUSED) { - function_name = EX_CONSTANT(opline->op2); + function_name = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST) { if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { @@ -19508,7 +25017,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { @@ -19598,29 +25107,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_ { zend_class_entry *ce, *scope; zend_class_constant *c; - zval *value; + zval *value, *zv; USE_OPLINE SAVE_OPLINE(); do { if (IS_VAR == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); -#ifdef ZTS - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); -#endif + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); break; - } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))))) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else { if (IS_VAR == IS_UNUSED) { @@ -19633,21 +25139,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_ } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); break; } } - if (EXPECTED((c = zend_hash_find_ptr(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { + zv = zend_hash_find_ex(&ce->constants_table, Z_STR_P(RT_CONSTANT(opline, opline->op2)), 1); + if (EXPECTED(zv != NULL)) { + c = Z_PTR_P(zv); scope = EX(func)->op_array.scope; if (!zend_verify_const_access(c, scope)) { - zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(ce->name), Z_STRVAL_P(EX_CONSTANT(opline->op2))); + zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(ce->name), Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } value = &c->value; - if (Z_CONSTANT_P(value)) { + if (Z_TYPE_P(value) == IS_CONSTANT_AST) { zval_update_constant_ex(value, c->ce); if (UNEXPECTED(EG(exception) != NULL)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -19655,26 +25163,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_ } } if (IS_VAR == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), value); } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce, value); } } else { - zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } } while (0); -#ifdef ZTS - if (ce->type == ZEND_INTERNAL_CLASS) { - ZVAL_DUP(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } -#else - ZVAL_COPY(EX_VAR(opline->result.var), value); -#endif + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); ZEND_VM_NEXT_OPCODE(); } @@ -19697,20 +25197,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CON if (IS_VAR == IS_TMP_VAR) { /* pass */ } else if (IS_VAR == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else if (IS_VAR == IS_CV) { ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else /* if (IS_VAR == IS_VAR) */ { if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { zend_refcounted *ref = Z_COUNTED_P(expr_ptr); expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; efree_size(ref, sizeof(zend_reference)); @@ -19723,7 +25219,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CON if (IS_CONST != IS_UNUSED) { - zval *offset = EX_CONSTANT(opline->op2); + zval *offset = RT_CONSTANT(opline, opline->op2); zend_string *str; zend_ulong hval; @@ -19762,13 +25258,13 @@ num_index: goto str_index; } else { zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -19783,20 +25279,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_CONST_HAND array = EX_VAR(opline->result.var); if (IS_VAR != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - - if (IS_VAR != IS_UNUSED) { + ZVAL_ARR(array, zend_new_array(size)); /* Explicitly initialize array as not-packed if flag is set */ if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init(Z_ARRVAL_P(array), 0); } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -19810,7 +25302,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDL SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - offset = EX_CONSTANT(opline->op2); + offset = RT_CONSTANT(opline, opline->op2); do { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -19902,7 +25394,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDL if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = EX_CONSTANT(opline->op2); + offset = RT_CONSTANT(opline, opline->op2); do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { @@ -20014,7 +25506,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z /* Set the new yielded key */ if (IS_CONST != IS_UNUSED) { - zval *key = EX_CONSTANT(opline->op2); + zval *key = RT_CONSTANT(opline, opline->op2); /* Consts, temporary variables and references need copying */ if (IS_CONST == IS_CONST) { @@ -20070,7 +25562,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLE USE_OPLINE zend_free_op free_op1; zval *op1; - HashTable *ht = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); + HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); int result; SAVE_OPLINE(); @@ -20105,6 +25597,2154 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +{ + USE_OPLINE + zend_free_op free_op1, free_op2, free_op_data1; + zval *object; + zval *property; + zval *value; + zval *zptr; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + do { + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { + zend_string *property_name = zval_get_string(property); + zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + break; + } + } + + /* here we are sure we are dealing with an object */ + if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + ZVAL_DEREF(zptr); + + binary_op(zptr, zptr, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), zptr); + } + } + } else { + zend_assign_op_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + } + } while (0); + + FREE_OP(free_op_data1); + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +{ + USE_OPLINE + zend_free_op free_op1, free_op2, free_op_data1; + zval *var_ptr; + zval *value, *container, *dim; + + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +assign_dim_op_array: + SEPARATE_ARRAY(container); +assign_dim_op_new_array: + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); + if (UNEXPECTED(!var_ptr)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + goto assign_dim_op_ret_null; + } + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + } else { + var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(!var_ptr)) { + goto assign_dim_op_ret_null; + } + ZVAL_DEREF(var_ptr); + } + + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + + binary_op(var_ptr, var_ptr, value); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + } + } else { + if (EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto assign_dim_op_array; + } + } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { + container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); +assign_dim_op_convert_to_array: + ZVAL_ARR(container, zend_new_array(8)); + goto assign_dim_op_new_array; + } + + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC); + } else { + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + } else { + zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC); + zend_wrong_string_offset(EXECUTE_DATA_C); + } + UNDEF_RESULT(); + } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + goto assign_dim_op_convert_to_array; + } else { + if (UNEXPECTED(IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(container)))) { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); + } +assign_dim_op_ret_null: + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + } + } + + zval_ptr_dtor_nogc(free_op2); + FREE_OP(free_op_data1); + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper_SPEC_VAR_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *var_ptr; + zval *value; + + SAVE_OPLINE(); + value = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + ZVAL_DEREF(var_ptr); + + binary_op(var_ptr, var_ptr, value); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + } + } + + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +{ +#if 1 && (IS_TMP_VAR|IS_VAR) == IS_UNUSED + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#else +# if 0 || IS_VAR != IS_UNUSED + USE_OPLINE + + if (EXPECTED(1)) { + ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } + if (EXPECTED(0)) { + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } +# endif + + ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#endif +} + +static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +{ +#if 1 && (IS_TMP_VAR|IS_VAR) == IS_UNUSED + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#else +# if 0 || IS_VAR != IS_UNUSED + USE_OPLINE + + if (EXPECTED(0)) { + ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } + if (EXPECTED(1)) { + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } +# endif + + ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#endif +} + +static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +{ +#if 1 && (IS_TMP_VAR|IS_VAR) == IS_UNUSED + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#else +# if 0 || IS_VAR != IS_UNUSED + USE_OPLINE + + if (EXPECTED(0)) { + ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } + if (EXPECTED(0)) { + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } +# endif + + ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#endif +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *object; + zval *property; + zval *zptr; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + do { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { + zend_string *property_name = zval_get_string(property); + zend_error(E_WARNING, "Attempt to increment/decrement property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + break; + } + } + + /* here we are sure we are dealing with an object */ + if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) { + if (inc) { + fast_long_increment_function(zptr); + } else { + fast_long_decrement_function(zptr); + } + } else { + ZVAL_DEREF(zptr); + + if (inc) { + increment_function(zptr); + } else { + decrement_function(zptr); + } + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), zptr); + } + } + } else { + zend_pre_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + } + } while (0); + + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *object; + zval *property; + zval *zptr; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + do { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { + zend_string *property_name = zval_get_string(property); + zend_error(E_WARNING, "Attempt to increment/decrement property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + ZVAL_NULL(EX_VAR(opline->result.var)); + break; + } + } + + /* here we are sure we are dealing with an object */ + + if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); + if (inc) { + fast_long_increment_function(zptr); + } else { + fast_long_decrement_function(zptr); + } + } else { + ZVAL_DEREF(zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); + if (inc) { + increment_function(zptr); + } else { + decrement_function(zptr); + } + } + } + } else { + zend_post_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); + } + } while (0); + + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *container; + + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); + } + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *container; + + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); + } + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use temporary expression in write context"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use [] for reading"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *container; + + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); + } + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *property; + zval *container; + + SAVE_OPLINE(); + + container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); + } + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *property; + zval *container; + + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); + } + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + /* Behave like FETCH_OBJ_W */ + if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use temporary expression in write context"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *container, *property; + + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); + } + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *retval, *container, *dim; + + SAVE_OPLINE(); + retval = EX_VAR(opline->result.var); + container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + if (IS_VAR == IS_VAR + && Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT + && UNEXPECTED(!Z_ISREF_P(container)) + ) { + zend_error(E_NOTICE, "Attempting to set reference to non referenceable value"); + zend_fetch_dimension_address_LIST_r(retval, container, dim EXECUTE_DATA_CC); + } else { + zend_fetch_dimension_address_LIST_w(retval, container, dim EXECUTE_DATA_CC); + } + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *object, *property, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = RT_CONSTANT((opline+1), (opline+1)->op1); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (Z_ISREF_P(object)) { + object = Z_REFVAL_P(object); + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + break; + } + } + if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE || + (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { + zend_object *obj; + + zval_ptr_dtor_nogc(object); + object_init(object); + Z_ADDREF_P(object); + obj = Z_OBJ_P(object); + zend_error(E_WARNING, "Creating default object from empty value"); + if (GC_REFCOUNT(obj) == 1) { + /* the enclosing container was deleted, obj is unreferenced */ + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + OBJ_RELEASE(obj); + goto exit_assign_obj; + } + Z_DELREF_P(object); + } else { + if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { + zend_string *property_name = zval_get_string(property); + zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + } while (0); + } + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property_val; + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property_val, value, IS_CONST); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); + if (property_val) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CONST != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CONST == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, Z_STR_P(property), value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } + + if (!Z_OBJ_HT_P(object)->write_property) { + zend_string *property_name = zval_get_string(property); + zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + +exit_assign_obj: + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2, free_op_data; + zval *object, *property, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (Z_ISREF_P(object)) { + object = Z_REFVAL_P(object); + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + break; + } + } + if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE || + (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { + zend_object *obj; + + zval_ptr_dtor_nogc(object); + object_init(object); + Z_ADDREF_P(object); + obj = Z_OBJ_P(object); + zend_error(E_WARNING, "Creating default object from empty value"); + if (GC_REFCOUNT(obj) == 1) { + /* the enclosing container was deleted, obj is unreferenced */ + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + OBJ_RELEASE(obj); + goto exit_assign_obj; + } + Z_DELREF_P(object); + } else { + if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { + zend_string *property_name = zval_get_string(property); + zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + } while (0); + } + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property_val; + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property_val, value, IS_TMP_VAR); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); + if (property_val) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_TMP_VAR == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, Z_STR_P(property), value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } + + if (!Z_OBJ_HT_P(object)->write_property) { + zend_string *property_name = zval_get_string(property); + zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + zval_ptr_dtor_nogc(free_op_data); +exit_assign_obj: + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2, free_op_data; + zval *object, *property, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = _get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (Z_ISREF_P(object)) { + object = Z_REFVAL_P(object); + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + break; + } + } + if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE || + (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { + zend_object *obj; + + zval_ptr_dtor_nogc(object); + object_init(object); + Z_ADDREF_P(object); + obj = Z_OBJ_P(object); + zend_error(E_WARNING, "Creating default object from empty value"); + if (GC_REFCOUNT(obj) == 1) { + /* the enclosing container was deleted, obj is unreferenced */ + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + OBJ_RELEASE(obj); + goto exit_assign_obj; + } + Z_DELREF_P(object); + } else { + if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { + zend_string *property_name = zval_get_string(property); + zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + } while (0); + } + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property_val; + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property_val, value, IS_VAR); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); + if (property_val) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_VAR != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_VAR == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, Z_STR_P(property), value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } + + if (!Z_OBJ_HT_P(object)->write_property) { + zend_string *property_name = zval_get_string(property); + zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + zval_ptr_dtor_nogc(free_op_data); +exit_assign_obj: + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *object, *property, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (Z_ISREF_P(object)) { + object = Z_REFVAL_P(object); + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + break; + } + } + if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE || + (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { + zend_object *obj; + + zval_ptr_dtor_nogc(object); + object_init(object); + Z_ADDREF_P(object); + obj = Z_OBJ_P(object); + zend_error(E_WARNING, "Creating default object from empty value"); + if (GC_REFCOUNT(obj) == 1) { + /* the enclosing container was deleted, obj is unreferenced */ + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + OBJ_RELEASE(obj); + goto exit_assign_obj; + } + Z_DELREF_P(object); + } else { + if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { + zend_string *property_name = zval_get_string(property); + zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + } while (0); + } + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property_val; + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property_val, value, IS_CV); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); + if (property_val) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CV != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CV == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, Z_STR_P(property), value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } + + if (!Z_OBJ_HT_P(object)->write_property) { + zend_string *property_name = zval_get_string(property); + zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + +exit_assign_obj: + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *object_ptr; + zend_free_op free_op2; + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + goto assign_dim_error; + } + } else { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + } + value = RT_CONSTANT((opline+1), (opline+1)->op1); + value = zend_assign_to_variable(variable_ptr, value, IS_CONST); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = RT_CONSTANT((opline+1), (opline+1)->op1); + + zend_assign_to_object_dim(object_ptr, dim, value); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = RT_CONSTANT((opline+1), (opline+1)->op1); + zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); + + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + ZVAL_ARR(object_ptr, zend_new_array(8)); + goto try_assign_dim_array; + } else { + if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); + } + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); +assign_dim_error: + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zval_ptr_dtor_nogc(free_op2); + } + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *object_ptr; + zend_free_op free_op2, free_op_data; + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + goto assign_dim_error; + } + } else { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + } + value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + + zend_assign_to_object_dim(object_ptr, dim, value); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + zval_ptr_dtor_nogc(free_op_data); + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op_data); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + ZVAL_ARR(object_ptr, zend_new_array(8)); + goto try_assign_dim_array; + } else { + if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); + } + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); +assign_dim_error: + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zval_ptr_dtor_nogc(free_op2); + } + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *object_ptr; + zend_free_op free_op2, free_op_data; + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + goto assign_dim_error; + } + } else { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + } + value = _get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + value = zend_assign_to_variable(variable_ptr, value, IS_VAR); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + + zend_assign_to_object_dim(object_ptr, dim, value); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + zval_ptr_dtor_nogc(free_op_data); + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op_data); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + ZVAL_ARR(object_ptr, zend_new_array(8)); + goto try_assign_dim_array; + } else { + if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); + } + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); +assign_dim_error: + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zval_ptr_dtor_nogc(free_op2); + } + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *object_ptr; + zend_free_op free_op2; + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + goto assign_dim_error; + } + } else { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + } + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable(variable_ptr, value, IS_CV); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + + zend_assign_to_object_dim(object_ptr, dim, value); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); + + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + ZVAL_ARR(object_ptr, zend_new_array(8)); + goto try_assign_dim_array; + } else { + if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); + } + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); +assign_dim_error: + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zval_ptr_dtor_nogc(free_op2); + } + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + zend_class_entry *ce; + zend_object *object; + zend_function *fbc; + zend_execute_data *call; + + SAVE_OPLINE(); + + if (IS_VAR == IS_CONST) { + /* no function found. try a static method in class */ + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + + if (IS_VAR == IS_CONST && + (IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { + /* nothing to do */ + } else if (IS_VAR != IS_CONST && + (IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zend_free_op free_op2; + + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Function name must be a string"); + zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); + } while (0); + } + } + + if (ce->get_static_method) { + fbc = ce->get_static_method(ce, Z_STR_P(function_name)); + } else { + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + } + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), Z_STRVAL_P(function_name)); + } + zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { + if (IS_VAR == IS_CONST) { + CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); + } else { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); + } + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { + init_func_run_time_cache(&fbc->op_array); + } + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zval_ptr_dtor_nogc(free_op2); + } + } else { + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); + } + if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { + zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); + HANDLE_EXCEPTION(); + } + fbc = ce->constructor; + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { + init_func_run_time_cache(&fbc->op_array); + } + } + + object = NULL; + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { + object = Z_OBJ(EX(This)); + ce = object->ce; + } else { + if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { + /* Allowed for PHP 4 compatibility. */ + zend_error( + E_DEPRECATED, + "Non-static method %s::%s() should not be called statically", + ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } else { + /* An internal function assumes $this is present and won't check that. + * So PHP would crash by allowing the call. */ + zend_throw_error( + zend_ce_error, + "Non-static method %s::%s() cannot be called statically", + ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); + HANDLE_EXCEPTION(); + } + } + } + + if (IS_VAR == IS_UNUSED) { + /* previous opcode is ZEND_FETCH_CLASS */ + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if (Z_TYPE(EX(This)) == IS_OBJECT) { + ce = Z_OBJCE(EX(This)); + } else { + ce = Z_CE(EX(This)); + } + } + } + + call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, ce, object); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *expr_ptr, new_expr; + + SAVE_OPLINE(); + if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && + UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { + expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + ZVAL_MAKE_REF(expr_ptr); + Z_ADDREF_P(expr_ptr); + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + } else { + expr_ptr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if (IS_VAR == IS_TMP_VAR) { + /* pass */ + } else if (IS_VAR == IS_CONST) { + Z_TRY_ADDREF_P(expr_ptr); + } else if (IS_VAR == IS_CV) { + ZVAL_DEREF(expr_ptr); + Z_TRY_ADDREF_P(expr_ptr); + } else /* if (IS_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(expr_ptr); + + expr_ptr = Z_REFVAL_P(expr_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + ZVAL_COPY_VALUE(&new_expr, expr_ptr); + expr_ptr = &new_expr; + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } + } + } + } + + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zend_free_op free_op2; + zval *offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + zend_string *str; + zend_ulong hval; + +add_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index; + } + } +str_index: + zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index: + zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto add_again; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index; + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else { + zend_error(E_WARNING, "Illegal offset type"); + zval_ptr_dtor_nogc(expr_ptr); + } + zval_ptr_dtor_nogc(free_op2); + } else { + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + zval_ptr_dtor_nogc(expr_ptr); + } + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zval *array; + uint32_t size; + USE_OPLINE + + array = EX_VAR(opline->result.var); + if (IS_VAR != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init(Z_ARRVAL_P(array), 0); + } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *container; + zval *offset; + zend_ulong hval; + zend_string *key; + + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + do { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + +unset_dim_array: + SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); +offset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + key = Z_STR_P(offset); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(key, hval)) { + goto num_index_dim; + } + } +str_index_dim: + if (ht == &EG(symbol_table)) { + zend_delete_global_variable(key); + } else { + zend_hash_del(ht, key); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_dim: + zend_hash_index_del(ht, hval); + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto offset_again; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_NULL) { + key = ZSTR_EMPTY_ALLOC(); + goto str_index_dim; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); + key = ZSTR_EMPTY_ALLOC(); + goto str_index_dim; + } else { + zend_error(E_WARNING, "Illegal offset type in unset"); + } + break; + } else if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto unset_dim_array; + } + } + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + container = GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); + } + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { + zend_throw_error(NULL, "Cannot use object as array"); + } else { + Z_OBJ_HT_P(container)->unset_dimension(container, offset); + } + } else if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { + zend_throw_error(NULL, "Cannot unset string offsets"); + } + } while (0); + + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *container; + zval *offset; + + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + do { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + break; + } + } else { + break; + } + } + if (Z_OBJ_HT_P(container)->unset_property) { + Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + } else { + zend_string *property_name = zval_get_string(offset); + zend_error(E_NOTICE, "Trying to unset property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + } + } while (0); + + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -20635,6 +28275,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP assign_dim_op_array: SEPARATE_ARRAY(container); assign_dim_op_new_array: + dim = NULL; if (IS_UNUSED == IS_UNUSED) { var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { @@ -20642,8 +28283,6 @@ assign_dim_op_new_array: goto assign_dim_op_ret_null; } } else { - dim = NULL; - if (IS_UNUSED == IS_CONST) { var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); } else { @@ -20653,10 +28292,9 @@ assign_dim_op_new_array: goto assign_dim_op_ret_null; } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); binary_op(var_ptr, var_ptr, value); @@ -20672,15 +28310,14 @@ assign_dim_op_new_array: } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(container, zend_new_array(8)); goto assign_dim_op_new_array; } dim = NULL; if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC); } else { if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { @@ -20702,7 +28339,7 @@ assign_dim_op_ret_null: ZVAL_NULL(EX_VAR(opline->result.var)); } } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); } } @@ -20830,40 +28467,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_H static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zend_free_op free_op1; - - SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED EXECUTE_DATA_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { if (IS_UNUSED == IS_UNUSED) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use [] for reading"); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, NULL, IS_UNUSED EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(free_op1); + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -20899,7 +28524,7 @@ try_assign_dim_array: goto assign_dim_error; } } - value = EX_CONSTANT((opline+1)->op1); + value = RT_CONSTANT((opline+1), (opline+1)->op1); value = zend_assign_to_variable(variable_ptr, value, IS_CONST); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -20913,7 +28538,7 @@ try_assign_dim_array: } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = NULL; - value = EX_CONSTANT((opline+1)->op1); + value = RT_CONSTANT((opline+1), (opline+1)->op1); zend_assign_to_object_dim(object_ptr, dim, value); @@ -20930,13 +28555,12 @@ try_assign_dim_array: HANDLE_EXCEPTION(); } else { dim = NULL; - value = EX_CONSTANT((opline+1)->op1); + value = RT_CONSTANT((opline+1), (opline+1)->op1); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { @@ -21028,8 +28652,7 @@ try_assign_dim_array: zval_ptr_dtor_nogc(free_op_data); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { @@ -21121,8 +28744,7 @@ try_assign_dim_array: zval_ptr_dtor_nogc(free_op_data); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { @@ -21213,8 +28835,7 @@ try_assign_dim_array: } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { @@ -21249,14 +28870,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -21271,12 +28892,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR == IS_CONST && IS_UNUSED == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { /* nothing to do */ } else if (IS_VAR != IS_CONST && IS_UNUSED == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); } else if (IS_UNUSED != IS_UNUSED) { @@ -21305,7 +28926,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { @@ -21459,20 +29080,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNU if (IS_VAR == IS_TMP_VAR) { /* pass */ } else if (IS_VAR == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else if (IS_VAR == IS_CV) { ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else /* if (IS_VAR == IS_VAR) */ { if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { zend_refcounted *ref = Z_COUNTED_P(expr_ptr); expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; efree_size(ref, sizeof(zend_reference)); @@ -21524,13 +29141,13 @@ num_index: goto str_index; } else { zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -21545,20 +29162,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HAN array = EX_VAR(opline->result.var); if (IS_VAR != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - - if (IS_VAR != IS_UNUSED) { + ZVAL_ARR(array, zend_new_array(size)); /* Explicitly initialize array as not-packed if flag is set */ if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init(Z_ARRVAL_P(array), 0); } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -21733,7 +29346,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MAKE_REF_SPEC_VAR_UNUSED_HANDL if (EXPECTED(!Z_ISREF_P(op1))) { ZVAL_MAKE_REF(op1); } - GC_REFCOUNT(Z_REF_P(op1))++; + GC_ADDREF(Z_REF_P(op1)); ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); } else { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), op1); @@ -21837,42 +29450,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_VAR_UNUSED_HANDL ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE @@ -21892,7 +29469,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); do { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -21916,7 +29493,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); binary_op(zptr, zptr, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -21949,6 +29525,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP assign_dim_op_array: SEPARATE_ARRAY(container); assign_dim_op_new_array: + dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (IS_CV == IS_UNUSED) { var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { @@ -21956,8 +29533,6 @@ assign_dim_op_new_array: goto assign_dim_op_ret_null; } } else { - dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (IS_CV == IS_CONST) { var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); } else { @@ -21967,10 +29542,9 @@ assign_dim_op_new_array: goto assign_dim_op_ret_null; } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); binary_op(var_ptr, var_ptr, value); @@ -21986,15 +29560,14 @@ assign_dim_op_new_array: } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(container, zend_new_array(8)); goto assign_dim_op_new_array; } dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC); } else { if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { @@ -22016,7 +29589,7 @@ assign_dim_op_ret_null: ZVAL_NULL(EX_VAR(opline->result.var)); } } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); } } @@ -22042,7 +29615,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper } } else { ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); binary_op(var_ptr, var_ptr, value); @@ -22342,7 +29914,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); if (inc) { increment_function(zptr); @@ -22418,8 +29989,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } else { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); - zval_opt_copy_ctor(zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); if (inc) { increment_function(zptr); } else { @@ -22485,40 +30055,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDL static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zend_free_op free_op1; - - SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { if (IS_CV == IS_UNUSED) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use [] for reading"); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(free_op1); + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -22539,79 +30097,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HA ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - - if (IS_VAR == IS_CONST || - (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_r_no_object; - } - } else { - goto fetch_obj_r_no_object; - } - } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zval *retval; - - if (IS_CV == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } - } - - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { - zend_string *property_name; -fetch_obj_r_no_object: - property_name = zval_get_string(offset); - zend_error(E_NOTICE, "Trying to get property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - } - } - } while (0); - - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -22662,36 +30147,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDL static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1; - zval *property; - - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -22719,6 +30189,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HA ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *retval, *container, *dim; + + SAVE_OPLINE(); + retval = EX_VAR(opline->result.var); + container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + + if (IS_VAR == IS_VAR + && Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT + && UNEXPECTED(!Z_ISREF_P(container)) + ) { + zend_error(E_NOTICE, "Attempting to set reference to non referenceable value"); + zend_fetch_dimension_address_LIST_r(retval, container, dim EXECUTE_DATA_CC); + } else { + zend_fetch_dimension_address_LIST_w(retval, container, dim EXECUTE_DATA_CC); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -22733,7 +30227,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - value = EX_CONSTANT((opline+1)->op1); + value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { do { @@ -22747,7 +30241,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -22779,11 +30273,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA if (IS_CV == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -22797,11 +30291,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -22820,24 +30314,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CONST == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -22905,7 +30395,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -22937,11 +30427,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA if (IS_CV == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -22955,11 +30445,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -22978,24 +30468,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_TMP_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -23063,7 +30549,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -23095,11 +30581,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA if (IS_CV == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -23113,11 +30599,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -23136,24 +30622,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -23221,7 +30703,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -23253,11 +30735,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA if (IS_CV == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -23271,11 +30753,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -23294,24 +30776,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CV == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CV == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -23384,7 +30862,7 @@ try_assign_dim_array: goto assign_dim_error; } } - value = EX_CONSTANT((opline+1)->op1); + value = RT_CONSTANT((opline+1), (opline+1)->op1); value = zend_assign_to_variable(variable_ptr, value, IS_CONST); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -23398,7 +30876,7 @@ try_assign_dim_array: } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - value = EX_CONSTANT((opline+1)->op1); + value = RT_CONSTANT((opline+1), (opline+1)->op1); zend_assign_to_object_dim(object_ptr, dim, value); @@ -23415,13 +30893,12 @@ try_assign_dim_array: HANDLE_EXCEPTION(); } else { dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - value = EX_CONSTANT((opline+1)->op1); + value = RT_CONSTANT((opline+1), (opline+1)->op1); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { @@ -23513,8 +30990,7 @@ try_assign_dim_array: zval_ptr_dtor_nogc(free_op_data); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { @@ -23606,8 +31082,7 @@ try_assign_dim_array: zval_ptr_dtor_nogc(free_op_data); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { @@ -23698,8 +31173,7 @@ try_assign_dim_array: } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { @@ -23847,14 +31321,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else if (IS_VAR == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -23869,12 +31343,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR == IS_CONST && IS_CV == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { /* nothing to do */ } else if (IS_VAR != IS_CONST && IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); } else if (IS_CV != IS_UNUSED) { @@ -23903,7 +31377,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { @@ -24007,20 +31481,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_ if (IS_VAR == IS_TMP_VAR) { /* pass */ } else if (IS_VAR == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else if (IS_VAR == IS_CV) { ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else /* if (IS_VAR == IS_VAR) */ { if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { zend_refcounted *ref = Z_COUNTED_P(expr_ptr); expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; efree_size(ref, sizeof(zend_reference)); @@ -24072,13 +31542,13 @@ num_index: goto str_index; } else { zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -24093,20 +31563,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER array = EX_VAR(opline->result.var); if (IS_VAR != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - - if (IS_VAR != IS_UNUSED) { + ZVAL_ARR(array, zend_new_array(size)); /* Explicitly initialize array as not-packed if flag is set */ if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init(Z_ARRVAL_P(array), 0); } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -24479,449 +31945,344 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SIMPLE_ } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2, free_op_data1; - zval *object; - zval *property; - zval *value; - zval *zptr; + zval *result; + zend_function *constructor; + zend_class_entry *ce; + zend_execute_data *call; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - do { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + result = EX_VAR(opline->result.var); + if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { + ZVAL_UNDEF(result); + HANDLE_EXCEPTION(); + } - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - ZVAL_DEREF(object); - if (UNEXPECTED(!make_real_object(object))) { - zend_string *property_name = zval_get_string(property); - zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - break; - } + constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); + if (constructor == NULL) { + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); } - /* here we are sure we are dealing with an object */ - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); + /* If there are no arguments, skip over the DO_FCALL opcode. We check if the next + * opcode is DO_FCALL in case EXT instructions are used. */ + if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) { + ZEND_VM_NEXT_OPCODE_EX(1, 2); + } - binary_op(zptr, zptr, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), zptr); - } - } - } else { - zend_assign_op_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + /* Perform a dummy function call */ + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, + opline->extended_value, NULL, NULL); + } else { + if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!constructor->op_array.run_time_cache)) { + init_func_run_time_cache(&constructor->op_array); } - } while (0); + /* We are not handling overloaded classes right now */ + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR, + constructor, + opline->extended_value, + ce, + Z_OBJ_P(result)); + Z_ADDREF_P(result); + } - FREE_OP(free_op_data1); - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2, free_op_data1; - zval *var_ptr; - zval *value, *container, *dim; + + zval *obj; + zend_class_entry *ce, *scope; + zend_function *clone; + zend_object_clone_obj_t clone_call; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + obj = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -assign_dim_op_array: - SEPARATE_ARRAY(container); -assign_dim_op_new_array: - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); - if (UNEXPECTED(!var_ptr)) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - goto assign_dim_op_ret_null; - } - } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); - } else { - var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + do { + if (IS_UNUSED == IS_CONST || + (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) { + obj = Z_REFVAL_P(obj); + if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) { + break; + } } - if (UNEXPECTED(!var_ptr)) { - goto assign_dim_op_ret_null; + ZVAL_UNDEF(EX_VAR(opline->result.var)); + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(obj, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } - ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); + zend_throw_error(NULL, "__clone method called on non-object"); + + HANDLE_EXCEPTION(); } + } while (0); - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + ce = Z_OBJCE_P(obj); + clone = ce->clone; + clone_call = Z_OBJ_HT_P(obj)->clone_obj; + if (UNEXPECTED(clone_call == NULL)) { + zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); - binary_op(var_ptr, var_ptr, value); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - } - } else { - if (EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto assign_dim_op_array; - } - } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { - container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); -assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto assign_dim_op_new_array; - } + if (clone) { + if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) { + /* Ensure that if we're calling a private function, we're allowed to do so. + */ + scope = EX(func)->op_array.scope; + if (!zend_check_private(clone, scope, clone->common.function_name)) { + zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : ""); - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) { + /* Ensure that if we're calling a protected function, we're allowed to do so. + */ + scope = EX(func)->op_array.scope; + if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) { + zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : ""); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); - zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC); - } else { - if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_throw_error(NULL, "[] operator not supported for strings"); - } else { - zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC); - zend_wrong_string_offset(EXECUTE_DATA_C); - } - UNDEF_RESULT(); - } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - goto assign_dim_op_convert_to_array; - } else { - if (UNEXPECTED(IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(container)))) { - zend_error(E_WARNING, "Cannot use a scalar value as an array"); - } -assign_dim_op_ret_null: - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); } } - zval_ptr_dtor_nogc(free_op2); - FREE_OP(free_op_data1); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper_SPEC_VAR_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2; - zval *var_ptr; - zval *value; SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + if (IS_UNUSED != IS_UNUSED) { - if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); + zval *ptr = NULL; - binary_op(var_ptr, var_ptr, value); + do { + if (Z_TYPE_P(ptr) == IS_LONG) { + EG(exit_status) = Z_LVAL_P(ptr); + } else { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(ptr)) { + ptr = Z_REFVAL_P(ptr); + if (Z_TYPE_P(ptr) == IS_LONG) { + EG(exit_status) = Z_LVAL_P(ptr); + break; + } + } + zend_print_variable(ptr); + } + } while (0); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - } } - - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + zend_bailout(); + ZEND_VM_NEXT_OPCODE(); /* Never reached */ } -static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { -#if 1 && (IS_TMP_VAR|IS_VAR) == IS_UNUSED - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -#else -# if 0 || IS_VAR != IS_UNUSED USE_OPLINE + zend_free_op free_op_data1; + zval *object; + zval *property; + zval *value; + zval *zptr; - if (EXPECTED(1)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } - if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + SAVE_OPLINE(); + object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); + + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -# endif - ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -#endif -} + property = RT_CONSTANT(opline, opline->op2); -static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) -{ -#if 1 && (IS_TMP_VAR|IS_VAR) == IS_UNUSED - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -#else -# if 0 || IS_VAR != IS_UNUSED - USE_OPLINE + do { + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); - if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } - if (EXPECTED(1)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } -# endif + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { + zend_string *property_name = zval_get_string(property); + zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + break; + } + } - ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -#endif + /* here we are sure we are dealing with an object */ + if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + ZVAL_DEREF(zptr); + + binary_op(zptr, zptr, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), zptr); + } + } + } else { + zend_assign_op_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + } + } while (0); + + FREE_OP(free_op_data1); + + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { -#if 1 && (IS_TMP_VAR|IS_VAR) == IS_UNUSED - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#if 1 && IS_CONST == IS_UNUSED + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #else -# if 0 || IS_VAR != IS_UNUSED +# if 0 || IS_UNUSED != IS_UNUSED USE_OPLINE if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_UNUSED_CONST(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } # endif - ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_VAR_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #endif } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_DIM(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_TMPVAR_OBJ(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - zend_free_op free_op1, free_op2; + zval *object; zval *property; zval *zptr; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + property = RT_CONSTANT(opline, opline->op2); do { - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); if (UNEXPECTED(!make_real_object(object))) { zend_string *property_name = zval_get_string(property); @@ -24936,7 +32297,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -24950,7 +32311,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); if (inc) { increment_function(zptr); @@ -24963,44 +32323,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } } else { - zend_pre_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_pre_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - zend_free_op free_op1, free_op2; + zval *object; zval *property; zval *zptr; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + property = RT_CONSTANT(opline, opline->op2); do { - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); if (UNEXPECTED(!make_real_object(object))) { zend_string *property_name = zval_get_string(property); @@ -25014,7 +32373,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -25027,8 +32386,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } else { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); - zval_opt_copy_ctor(zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); if (inc) { increment_function(zptr); } else { @@ -25037,145 +32395,59 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } } else { - zend_post_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); + zend_post_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); } } while (0); - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *container; - - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *container; - - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_UNUSED_CONST(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *container; - zend_free_op free_op1, free_op2; - - SAVE_OPLINE(); - - if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { - zend_throw_error(NULL, "Cannot use temporary expression in write context"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_throw_error(NULL, "Cannot use [] for reading"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_UNUSED_CONST(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2; - zval *container; - - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; zval *container; - zend_free_op free_op2; + zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + offset = RT_CONSTANT(opline, opline->op2); - if (IS_VAR == IS_CONST || - (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_r_no_object; + if (IS_UNUSED == IS_CONST || + (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - } else { goto fetch_obj_r_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -25183,23 +32455,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_TMPVAR_HA zend_object *zobj = Z_OBJ_P(container); zval *retval; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if (IS_CONST == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } } } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (UNEXPECTED(zobj->handlers->read_property == NULL)) { @@ -25210,7 +32506,7 @@ fetch_obj_r_no_object: zend_string_release(property_name); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); @@ -25218,135 +32514,213 @@ fetch_obj_r_no_object: } } while (0); - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2; + zend_free_op free_op1; zval *property; zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - zval_ptr_dtor_nogc(free_op2); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { + property = RT_CONSTANT(opline, opline->op2); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2; + zend_free_op free_op1; zval *property; zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); - zval_ptr_dtor_nogc(free_op2); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { + property = RT_CONSTANT(opline, opline->op2); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *container; - if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1, free_op2; - zval *property; + zval *offset; + void **cache_slot = NULL; - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + SAVE_OPLINE(); + container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + offset = RT_CONSTANT(opline, opline->op2); + + if (IS_UNUSED == IS_CONST || + (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + goto fetch_obj_is_no_object; + } while (0); + } + + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zval *retval; + + if (IS_CONST == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); + + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } } - if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { + + if (UNEXPECTED(zobj->handlers->read_property == NULL)) { +fetch_obj_is_no_object: + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } + } while (0); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + /* Behave like FETCH_OBJ_W */ + if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + + ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - zval_ptr_dtor_nogc(free_op2); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2; + zend_free_op free_op1; zval *container, *property; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + property = RT_CONSTANT(opline, opline->op2); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); - zval_ptr_dtor_nogc(free_op2); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2; + zval *object, *property, *value, tmp; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = EX_CONSTANT((opline+1)->op1); + property = RT_CONSTANT(opline, opline->op2); + value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { do { if (Z_ISREF_P(object)) { object = Z_REFVAL_P(object); @@ -25358,7 +32732,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -25374,7 +32748,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } Z_DELREF_P(object); } else { - if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { + if (IS_UNUSED != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { zend_string *property_name = zval_get_string(property); zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); zend_string_release(property_name); @@ -25388,13 +32762,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } while (0); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CONST == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -25408,11 +32782,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -25431,24 +32805,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CONST == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -25475,36 +32845,36 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } exit_assign_obj: - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + + /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2, free_op_data; + zend_free_op free_op_data; zval *object, *property, *value, tmp; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + property = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { do { if (Z_ISREF_P(object)) { object = Z_REFVAL_P(object); @@ -25516,7 +32886,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -25532,7 +32902,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } Z_DELREF_P(object); } else { - if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { + if (IS_UNUSED != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { zend_string *property_name = zval_get_string(property); zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); zend_string_release(property_name); @@ -25546,13 +32916,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } while (0); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CONST == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -25566,11 +32936,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -25589,24 +32959,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_TMP_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -25633,36 +32999,36 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); exit_assign_obj: - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + + /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2, free_op_data; + zend_free_op free_op_data; zval *object, *property, *value, tmp; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + property = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { do { if (Z_ISREF_P(object)) { object = Z_REFVAL_P(object); @@ -25674,7 +33040,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -25690,7 +33056,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } Z_DELREF_P(object); } else { - if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { + if (IS_UNUSED != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { zend_string *property_name = zval_get_string(property); zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); zend_string_release(property_name); @@ -25704,13 +33070,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } while (0); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CONST == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -25724,11 +33090,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -25747,24 +33113,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -25791,36 +33153,36 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); exit_assign_obj: - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + + /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2; + zval *object, *property, *value, tmp; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + property = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { do { if (Z_ISREF_P(object)) { object = Z_REFVAL_P(object); @@ -25832,7 +33194,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -25848,7 +33210,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } Z_DELREF_P(object); } else { - if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { + if (IS_UNUSED != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { zend_string *property_name = zval_get_string(property); zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); zend_string_release(property_name); @@ -25862,13 +33224,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } while (0); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CONST == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -25882,11 +33244,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -25905,24 +33267,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CV == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CV == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -25949,390 +33307,183 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } exit_assign_obj: - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + + /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1; - zval *object_ptr; - zend_free_op free_op2; - zval *value; - zval *variable_ptr; - zval *dim; - SAVE_OPLINE(); - object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + zend_string **rope; + zval *var; - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); - if (UNEXPECTED(variable_ptr == NULL)) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - goto assign_dim_error; - } - } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - } - value = EX_CONSTANT((opline+1)->op1); - value = zend_assign_to_variable(variable_ptr, value, IS_CONST); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + /* Compiler allocates the necessary number of zval slots to keep the rope */ + rope = (zend_string**)EX_VAR(opline->result.var); + if (IS_CONST == IS_CONST) { + var = RT_CONSTANT(opline, opline->op2); + rope[0] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); } } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = EX_CONSTANT((opline+1)->op1); - - zend_assign_to_object_dim(object_ptr, dim, value); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_throw_error(NULL, "[] operator not supported for strings"); - - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - UNDEF_RESULT(); - HANDLE_EXCEPTION(); + var = RT_CONSTANT(opline, opline->op2); + if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { + if (IS_CONST == IS_CV) { + rope[0] = zend_string_copy(Z_STR_P(var)); } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = EX_CONSTANT((opline+1)->op1); - zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); - + rope[0] = Z_STR_P(var); } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); - goto try_assign_dim_array; } else { - if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { - zend_error(E_WARNING, "Cannot use a scalar value as an array"); + SAVE_OPLINE(); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(var, BP_VAR_R); } - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); -assign_dim_error: + rope[0] = zval_get_string_func(var); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(free_op2); - } - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1; - zval *object_ptr; - zend_free_op free_op2, free_op_data; - zval *value; - zval *variable_ptr; - zval *dim; + zval *function_name; + + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; SAVE_OPLINE(); - object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); - if (UNEXPECTED(variable_ptr == NULL)) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - goto assign_dim_error; - } - } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - } - value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); - value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - zend_assign_to_object_dim(object_ptr, dim, value); + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } + function_name = RT_CONSTANT(opline, opline->op2); - zval_ptr_dtor_nogc(free_op_data); - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_throw_error(NULL, "[] operator not supported for strings"); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); - goto try_assign_dim_array; - } else { - if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { - zend_error(E_WARNING, "Cannot use a scalar value as an array"); - } - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); + if (IS_CONST != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(function_name, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { + + HANDLE_EXCEPTION(); + } } - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(free_op2); - } - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} + zend_throw_error(NULL, "Method name must be a string"); -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *object_ptr; - zend_free_op free_op2, free_op_data; - zval *value; - zval *variable_ptr; - zval *dim; - SAVE_OPLINE(); - object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + HANDLE_EXCEPTION(); + } while (0); + } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); - if (UNEXPECTED(variable_ptr == NULL)) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - goto assign_dim_error; - } - } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - } - value = _get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); - value = zend_assign_to_variable(variable_ptr, value, IS_VAR); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + if (IS_UNUSED != IS_UNUSED) { + do { + if (IS_UNUSED == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + object = Z_REFVAL_P(object); + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + break; + } + } + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = GET_OP1_UNDEF_CV(object, BP_VAR_R); + if (UNEXPECTED(EG(exception) != NULL)) { - zend_assign_to_object_dim(object_ptr, dim, value); + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(free_op_data); - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_throw_error(NULL, "[] operator not supported for strings"); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - UNDEF_RESULT(); HANDLE_EXCEPTION(); - } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); - goto try_assign_dim_array; - } else { - if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { - zend_error(E_WARNING, "Cannot use a scalar value as an array"); - } - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); } - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(free_op2); + } while (0); } - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *object_ptr; - zend_free_op free_op2; - zval *value; - zval *variable_ptr; - zval *dim; - - SAVE_OPLINE(); - object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + obj = Z_OBJ_P(object); + called_scope = obj->ce; - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); - if (UNEXPECTED(variable_ptr == NULL)) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - goto assign_dim_error; - } - } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - } - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable(variable_ptr, value, IS_CV); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } + if (IS_CONST == IS_CONST && + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - zend_assign_to_object_dim(object_ptr, dim, value); + zend_object *orig_obj = obj; - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } + if (UNEXPECTED(obj->handlers->get_method == NULL)) { + zend_throw_error(NULL, "Object does not support method calls"); - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_throw_error(NULL, "[] operator not supported for strings"); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); + HANDLE_EXCEPTION(); + } + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); - goto try_assign_dim_array; - } else { - if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { - zend_error(E_WARNING, "Cannot use a scalar value as an array"); - } - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); -assign_dim_error: - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } + + HANDLE_EXCEPTION(); + } + if (IS_CONST == IS_CONST && + EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { + init_func_run_time_cache(&fbc->op_array); } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(free_op2); + + call_info = ZEND_CALL_NESTED_FUNCTION; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + obj = NULL; + } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; + GC_ADDREF(obj); /* For $this pointer */ } - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + + + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, called_scope, obj); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -26343,56 +33494,56 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V SAVE_OPLINE(); - if (IS_VAR == IS_CONST) { + if (IS_UNUSED == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } - } else if (IS_VAR == IS_UNUSED) { + } else if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); } } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (IS_VAR == IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { + if (IS_UNUSED == IS_CONST && + IS_CONST == IS_CONST && + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { /* nothing to do */ - } else if (IS_VAR != IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); - } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zend_free_op free_op2; + } else if (IS_UNUSED != IS_CONST && + IS_CONST == IS_CONST && + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + } else if (IS_CONST != IS_UNUSED) { - function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + + function_name = RT_CONSTANT(opline, opline->op2); + if (IS_CONST != IS_CONST) { if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + if (IS_CONST & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { GET_OP2_UNDEF_CV(function_name, BP_VAR_R); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } } zend_throw_error(NULL, "Function name must be a string"); - zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); } while (0); } @@ -26401,19 +33552,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), Z_STRVAL_P(function_name)); } - zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CONST == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (IS_VAR == IS_CONST) { + if (IS_UNUSED == IS_CONST) { CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); } else { CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); @@ -26422,8 +33573,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(free_op2); + if (IS_CONST != IS_CONST) { + } } else { if (UNEXPECTED(ce->constructor == NULL)) { @@ -26467,7 +33618,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } } - if (IS_VAR == IS_UNUSED) { + if (IS_UNUSED == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { @@ -26487,234 +33638,135 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1; - zval *expr_ptr, new_expr; - - SAVE_OPLINE(); - if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && - UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - ZVAL_MAKE_REF(expr_ptr); - Z_ADDREF_P(expr_ptr); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - } else { - expr_ptr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if (IS_VAR == IS_TMP_VAR) { - /* pass */ - } else if (IS_VAR == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } else if (IS_VAR == IS_CV) { - ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } else /* if (IS_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(expr_ptr); - - expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { - ZVAL_COPY_VALUE(&new_expr, expr_ptr); - expr_ptr = &new_expr; - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } - } - } + zend_constant *c; - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zend_free_op free_op2; - zval *offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - zend_string *str; - zend_ulong hval; + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { + c = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + } else if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->extended_value)) == NULL) { + SAVE_OPLINE(); -add_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index; - } + if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { + char *actual = (char *)zend_memrchr(Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)), '\\', Z_STRLEN_P(RT_CONSTANT(opline, opline->op2))); + if (!actual) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(RT_CONSTANT(opline, opline->op2))); + } else { + actual++; + ZVAL_STRINGL(EX_VAR(opline->result.var), + actual, Z_STRLEN_P(RT_CONSTANT(opline, opline->op2)) - (actual - Z_STRVAL_P(RT_CONSTANT(opline, opline->op2)))); } -str_index: - zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index: - zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto add_again; - } else if (Z_TYPE_P(offset) == IS_NULL) { - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval(Z_DVAL_P(offset)); - goto num_index; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - GET_OP2_UNDEF_CV(offset, BP_VAR_R); - str = ZSTR_EMPTY_ALLOC(); - goto str_index; + /* non-qualified constant - allow text substitution */ + zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)", + Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var))); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); + zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } - zval_ptr_dtor_nogc(free_op2); } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); - } + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), c); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zval *array; - uint32_t size; - USE_OPLINE - - array = EX_VAR(opline->result.var); - if (IS_VAR != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); - if (IS_VAR != IS_UNUSED) { - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init(Z_ARRVAL_P(array), 0); - } - } - - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zend_class_entry *ce, *scope; + zend_class_constant *c; + zval *value, *zv; USE_OPLINE - zend_free_op free_op1, free_op2; - zval *container; - zval *offset; - zend_ulong hval; - zend_string *key; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - -unset_dim_array: - SEPARATE_ARRAY(container); - ht = Z_ARRVAL_P(container); -offset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - key = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(key, hval)) { - goto num_index_dim; - } + if (IS_UNUSED == IS_CONST) { + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))))) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + break; + } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))))) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); + } else { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } -str_index_dim: - if (ht == &EG(symbol_table)) { - zend_delete_global_variable(key); - } else { - zend_hash_del(ht, key); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); + } + } else { + if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_dim: - zend_hash_index_del(ht, hval); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto offset_again; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval(Z_DVAL_P(offset)); - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_NULL) { - key = ZSTR_EMPTY_ALLOC(); - goto str_index_dim; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - GET_OP2_UNDEF_CV(offset, BP_VAR_R); - key = ZSTR_EMPTY_ALLOC(); - goto str_index_dim; } else { - zend_error(E_WARNING, "Illegal offset type in unset"); + ce = Z_CE_P(EX_VAR(opline->op1.var)); } - break; - } else if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto unset_dim_array; + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + break; } } - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - container = GET_OP1_UNDEF_CV(container, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { - offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); - } - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { - zend_throw_error(NULL, "Cannot use object as array"); + + zv = zend_hash_find_ex(&ce->constants_table, Z_STR_P(RT_CONSTANT(opline, opline->op2)), 1); + if (EXPECTED(zv != NULL)) { + c = Z_PTR_P(zv); + scope = EX(func)->op_array.scope; + if (!zend_verify_const_access(c, scope)) { + zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(ce->name), Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + value = &c->value; + if (Z_TYPE_P(value) == IS_CONSTANT_AST) { + zval_update_constant_ex(value, c->ce); + if (UNEXPECTED(EG(exception) != NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } + if (IS_UNUSED == IS_CONST) { + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), value); } else { - Z_OBJ_HT_P(container)->unset_dimension(container, offset); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce, value); } - } else if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { - zend_throw_error(NULL, "Cannot unset string offsets"); + } else { + zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } } while (0); - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2; + zval *container; zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + offset = RT_CONSTANT(opline, opline->op2); do { - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if (Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (Z_TYPE_P(container) != IS_OBJECT) { @@ -26725,7 +33777,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HAND } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } else { zend_string *property_name = zval_get_string(offset); zend_error(E_NOTICE, "Trying to unset property '%s' of non-object", ZSTR_VAL(property_name)); @@ -26733,193 +33785,196 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HAND } } while (0); - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *result; - zend_function *constructor; - zend_class_entry *ce; - zend_execute_data *call; + + zval *container; + int result; + zval *offset; SAVE_OPLINE(); - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); - } - } else if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } + container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - result = EX_VAR(opline->result.var); - if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { - ZVAL_UNDEF(result); - HANDLE_EXCEPTION(); + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); - if (constructor == NULL) { - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } + offset = RT_CONSTANT(opline, opline->op2); - /* If there are no arguments, skip over the DO_FCALL opcode. We check if the next - * opcode is DO_FCALL in case EXT instructions are used. */ - if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) { - ZEND_VM_NEXT_OPCODE_EX(1, 2); + if (IS_UNUSED == IS_CONST || + (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + goto isset_no_object; + } + } else { + goto isset_no_object; } - - /* Perform a dummy function call */ - call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, - opline->extended_value, NULL, NULL); + } + if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { + zend_string *property_name = zval_get_string(offset); + zend_error(E_NOTICE, "Trying to check property '%s' of non-object", ZSTR_VAL(property_name)); + zend_string_release(property_name); +isset_no_object: + result = ((opline->extended_value & ZEND_ISSET) == 0); } else { - if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!constructor->op_array.run_time_cache)) { - init_func_run_time_cache(&constructor->op_array); - } - /* We are not handling overloaded classes right now */ - call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR, - constructor, - opline->extended_value, - ce, - Z_OBJ_P(result)); - Z_ADDREF_P(result); + result = + ((opline->extended_value & ZEND_ISSET) == 0) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *obj; - zend_class_entry *ce, *scope; - zend_function *clone; - zend_object_clone_obj_t clone_call; + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); SAVE_OPLINE(); - obj = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + zend_throw_error(NULL, "Cannot yield from finally in a force-closed generator"); - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + + UNDEF_RESULT(); + HANDLE_EXCEPTION(); } - do { - if (IS_UNUSED == IS_CONST || - (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) { - obj = Z_REFVAL_P(obj); - if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) { - break; + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); + + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); + + /* Set the new yielded value */ + if (IS_UNUSED != IS_UNUSED) { + + + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_UNUSED & (IS_CONST|IS_TMP_VAR)) { + zval *value; + + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + + value = NULL; + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_UNUSED == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } } - } - ZVAL_UNDEF(EX_VAR(opline->result.var)); - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { - GET_OP1_UNDEF_CV(obj, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + } else { + zval *value_ptr = NULL; + + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + if (IS_UNUSED == IS_VAR && + (value_ptr == &EG(uninitialized_zval) || + (opline->extended_value == ZEND_RETURNS_FUNCTION && + !Z_ISREF_P(value_ptr)))) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } else { + ZVAL_MAKE_REF(value_ptr); } - } - zend_throw_error(NULL, "__clone method called on non-object"); + ZVAL_COPY(&generator->value, value_ptr); - HANDLE_EXCEPTION(); - } - } while (0); + } + } else { + zval *value = NULL; - ce = Z_OBJCE_P(obj); - clone = ce->clone; - clone_call = Z_OBJ_HT_P(obj)->clone_obj; - if (UNEXPECTED(clone_call == NULL)) { - zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); + /* Consts, temporary variables and references need copying */ + if (IS_UNUSED == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } else if (IS_UNUSED == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); + } else { + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_UNUSED == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } + } + } + } else { + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); } - if (clone) { - if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) { - /* Ensure that if we're calling a private function, we're allowed to do so. - */ - scope = EX(func)->op_array.scope; - if (!zend_check_private(clone, scope, clone->common.function_name)) { - zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : ""); + /* Set the new yielded key */ + if (IS_CONST != IS_UNUSED) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); + zval *key = RT_CONSTANT(opline, opline->op2); + + /* Consts, temporary variables and references need copying */ + if (IS_CONST == IS_CONST) { + ZVAL_COPY_VALUE(&generator->key, key); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->key))) { + Z_ADDREF(generator->key); } - } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) { - /* Ensure that if we're calling a protected function, we're allowed to do so. - */ - scope = EX(func)->op_array.scope; - if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) { - zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : ""); + } else if (IS_CONST == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->key, key); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) { + ZVAL_COPY(&generator->key, Z_REFVAL_P(key)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); + } else { + ZVAL_COPY_VALUE(&generator->key, key); + if (IS_CONST == IS_CV) { + if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key); } } - } - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); + } + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; + } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); - if (IS_UNUSED != IS_UNUSED) { - zval *ptr = NULL; - - do { - if (Z_TYPE_P(ptr) == IS_LONG) { - EG(exit_status) = Z_LVAL_P(ptr); - } else { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(ptr)) { - ptr = Z_REFVAL_P(ptr); - if (Z_TYPE_P(ptr) == IS_LONG) { - EG(exit_status) = Z_LVAL_P(ptr); - break; - } - } - zend_print_variable(ptr); - } - } while (0); - - } - zend_bailout(); - ZEND_VM_NEXT_OPCODE(); /* Never reached */ + ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - zend_free_op free_op_data1; + zend_free_op free_op2, free_op_data1; zval *object; zval *property; zval *value; @@ -26932,10 +33987,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -26952,14 +34007,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); binary_op(zptr, zptr, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -26967,101 +34021,101 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } } else { - zend_assign_op_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_assign_op_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); FREE_OP(free_op_data1); - + zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { -#if 1 && IS_CONST == IS_UNUSED - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#if 1 && (IS_TMP_VAR|IS_VAR) == IS_UNUSED + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #else # if 0 || IS_UNUSED != IS_UNUSED USE_OPLINE if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_UNUSED_CONST(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_UNUSED_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } # endif - ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #endif } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zend_free_op free_op2; zval *object; zval *property; zval *zptr; @@ -27073,7 +34127,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -27091,7 +34145,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -27105,7 +34159,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); if (inc) { increment_function(zptr); @@ -27118,28 +34171,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } } else { - zend_pre_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_pre_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zend_free_op free_op2; zval *object; zval *property; zval *zptr; @@ -27151,7 +34205,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -27168,7 +34222,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -27181,8 +34235,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } else { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); - zval_opt_copy_ctor(zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); if (inc) { increment_function(zptr); } else { @@ -27191,31 +34244,33 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } } else { - zend_post_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); + zend_post_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); } } while (0); + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_UNUSED_CONST(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_UNUSED_CONST(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; - + zend_free_op free_op2; zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); @@ -27224,18 +34279,25 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_ ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = EX_CONSTANT(opline->op2); + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_r_no_object; + do { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - } else { goto fetch_obj_r_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -27243,23 +34305,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_ zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (IS_CONST == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } } } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (UNEXPECTED(zobj->handlers->read_property == NULL)) { @@ -27270,7 +34356,7 @@ fetch_obj_r_no_object: zend_string_release(property_name); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); @@ -27278,14 +34364,15 @@ fetch_obj_r_no_object: } } while (0); + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1; + zend_free_op free_op1, free_op2; zval *property; zval *container; @@ -27296,9 +34383,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_ ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -27306,10 +34393,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1; + zend_free_op free_op1, free_op2; zval *property; zval *container; @@ -27319,9 +34406,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); - + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zval_ptr_dtor_nogc(free_op2); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -27329,13 +34416,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; - + zend_free_op free_op2; zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); @@ -27344,18 +34432,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = EX_CONSTANT(opline->op2); + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_is_no_object; + do { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } } - } else { goto fetch_obj_is_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -27363,21 +34452,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (IS_CONST == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } } } } @@ -27387,7 +34498,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -27395,50 +34506,36 @@ fetch_obj_is_no_object: } } while (0); + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1; - zval *property; - - SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - property = EX_CONSTANT(opline->op2); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1; + zend_free_op free_op1, free_op2; zval *container, *property; SAVE_OPLINE(); @@ -27448,10 +34545,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CO ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); - - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zval_ptr_dtor_nogc(free_op2); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -27459,10 +34556,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CO ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -27472,8 +34569,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); - value = EX_CONSTANT((opline+1)->op1); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { do { @@ -27487,7 +34584,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -27517,13 +34614,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } while (0); } - if (IS_CONST == IS_CONST && + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -27537,11 +34634,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -27560,24 +34657,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CONST == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -27604,23 +34697,23 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } exit_assign_obj: - + zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op_data; + zend_free_op free_op2, free_op_data; zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -27630,7 +34723,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -27645,7 +34738,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -27675,13 +34768,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } while (0); } - if (IS_CONST == IS_CONST && + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -27695,11 +34788,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -27718,24 +34811,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_TMP_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -27762,23 +34851,23 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); exit_assign_obj: - + zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op_data; + zend_free_op free_op2, free_op_data; zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -27788,7 +34877,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); value = _get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -27803,7 +34892,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -27833,13 +34922,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } while (0); } - if (IS_CONST == IS_CONST && + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -27853,11 +34942,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -27876,24 +34965,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -27920,23 +35005,23 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); exit_assign_obj: - + zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -27946,7 +35031,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -27961,7 +35046,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -27991,13 +35076,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } while (0); } - if (IS_CONST == IS_CONST && + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -28011,11 +35096,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -28034,24 +35119,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CV == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CV == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -28078,57 +35159,60 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } exit_assign_obj: - + zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zend_string **rope; zval *var; /* Compiler allocates the necessary number of zval slots to keep the rope */ rope = (zend_string**)EX_VAR(opline->result.var); - if (IS_CONST == IS_CONST) { - var = EX_CONSTANT(opline->op2); - rope[0] = zend_string_copy(Z_STR_P(var)); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + var = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + rope[0] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); + } } else { - var = EX_CONSTANT(opline->op2); + var = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if (IS_CONST == IS_CV) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV) { rope[0] = zend_string_copy(Z_STR_P(var)); } else { rope[0] = Z_STR_P(var); } } else { SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { GET_OP2_UNDEF_CV(var, BP_VAR_R); } - rope[0] = _zval_get_string_func(var); - + rope[0] = zval_get_string_func(var); + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } } ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; - + zend_free_op free_op2; zval *object; zend_function *fbc; zend_class_entry *called_scope; @@ -28144,17 +35228,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = EX_CONSTANT(opline->op2); + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (IS_CONST != IS_CONST && + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { GET_OP2_UNDEF_CV(function_name, BP_VAR_R); if (UNEXPECTED(EG(exception) != NULL)) { @@ -28162,7 +35246,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C } } zend_throw_error(NULL, "Method name must be a string"); - + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } while (0); @@ -28180,12 +35264,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { object = GET_OP1_UNDEF_CV(object, BP_VAR_R); if (UNEXPECTED(EG(exception) != NULL)) { - + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } @@ -28195,7 +35279,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C obj = Z_OBJ_P(object); called_scope = obj->ce; - if (IS_CONST == IS_CONST && + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); } else { @@ -28203,22 +35287,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C if (UNEXPECTED(obj->handlers->get_method == NULL)) { zend_throw_error(NULL, "Object does not support method calls"); - + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); } - + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_CONST == IS_CONST && + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { @@ -28235,9 +35319,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(obj)++; /* For $this pointer */ + GC_ADDREF(obj); /* For $this pointer */ } + zval_ptr_dtor_nogc(free_op2); if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -28251,7 +35336,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -28264,20 +35349,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_UNUSED == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } } else { @@ -28285,33 +35370,33 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U } if (IS_UNUSED == IS_CONST && - IS_CONST == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { + (IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { /* nothing to do */ } else if (IS_UNUSED != IS_CONST && - IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); - } else if (IS_CONST != IS_UNUSED) { - + (IS_TMP_VAR|IS_VAR) == IS_CONST && + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); + } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zend_free_op free_op2; - function_name = EX_CONSTANT(opline->op2); - if (IS_CONST != IS_CONST) { + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if (IS_CONST & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { GET_OP2_UNDEF_CV(function_name, BP_VAR_R); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } } zend_throw_error(NULL, "Function name must be a string"); - + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } while (0); } @@ -28320,16 +35405,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), Z_STRVAL_P(function_name)); } - + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_CONST == IS_CONST && + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { if (IS_UNUSED == IS_CONST) { @@ -28341,8 +35426,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { init_func_run_time_cache(&fbc->op_array); } - if (IS_CONST != IS_CONST) { - + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zval_ptr_dtor_nogc(free_op2); } } else { if (UNEXPECTED(ce->constructor == NULL)) { @@ -28406,140 +35491,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_constant *c; - - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - } else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op2) + 1, opline->extended_value)) == NULL) { - SAVE_OPLINE(); - - if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { - char *actual = (char *)zend_memrchr(Z_STRVAL_P(EX_CONSTANT(opline->op2)), '\\', Z_STRLEN_P(EX_CONSTANT(opline->op2))); - if (!actual) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_STR_P(EX_CONSTANT(opline->op2))); - } else { - actual++; - ZVAL_STRINGL(EX_VAR(opline->result.var), - actual, Z_STRLEN_P(EX_CONSTANT(opline->op2)) - (actual - Z_STRVAL_P(EX_CONSTANT(opline->op2)))); - } - /* non-qualified constant - allow text substitution */ - zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)", - Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var))); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c); - } - -#ifdef ZTS - if (c->flags & CONST_PERSISTENT) { - ZVAL_DUP(EX_VAR(opline->result.var), &c->value); - } else { - ZVAL_COPY(EX_VAR(opline->result.var), &c->value); - } -#else - ZVAL_COPY(EX_VAR(opline->result.var), &c->value); -#endif - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zend_class_entry *ce, *scope; - zend_class_constant *c; - zval *value; - USE_OPLINE - - SAVE_OPLINE(); - - do { - if (IS_UNUSED == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); -#ifdef ZTS - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); -#endif - break; - } else if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))))) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); - } - } else { - if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); - break; - } - } - - if (EXPECTED((c = zend_hash_find_ptr(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { - scope = EX(func)->op_array.scope; - if (!zend_verify_const_access(c, scope)) { - zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(ce->name), Z_STRVAL_P(EX_CONSTANT(opline->op2))); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - value = &c->value; - if (Z_CONSTANT_P(value)) { - zval_update_constant_ex(value, c->ce); - if (UNEXPECTED(EG(exception) != NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } - if (IS_UNUSED == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); - } - } else { - zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } while (0); - -#ifdef ZTS - if (ce->type == ZEND_INTERNAL_CLASS) { - ZVAL_DUP(EX_VAR(opline->result.var), value); - } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } -#else - ZVAL_COPY(EX_VAR(opline->result.var), value); -#endif - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *container; zval *offset; @@ -28548,7 +35503,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HA if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = EX_CONSTANT(opline->op2); + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { @@ -28562,7 +35517,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HA } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } else { zend_string *property_name = zval_get_string(offset); zend_error(E_NOTICE, "Trying to unset property '%s' of non-object", ZSTR_VAL(property_name)); @@ -28570,14 +35525,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HA } } while (0); + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *container; int result; zval *offset; @@ -28589,7 +35545,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = EX_CONSTANT(opline->op2); + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -28611,151 +35567,16 @@ isset_no_object: } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } + zval_ptr_dtor_nogc(free_op2); ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - - SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - zend_throw_error(NULL, "Cannot yield from finally in a force-closed generator"); - - - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); - - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); - - /* Set the new yielded value */ - if (IS_UNUSED != IS_UNUSED) { - - - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_UNUSED & (IS_CONST|IS_TMP_VAR)) { - zval *value; - - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - - value = NULL; - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_UNUSED == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } - } else { - zval *value_ptr = NULL; - - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - if (IS_UNUSED == IS_VAR && - (value_ptr == &EG(uninitialized_zval) || - (opline->extended_value == ZEND_RETURNS_FUNCTION && - !Z_ISREF_P(value_ptr)))) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - } else { - ZVAL_MAKE_REF(value_ptr); - } - ZVAL_COPY(&generator->value, value_ptr); - - } - } else { - zval *value = NULL; - - /* Consts, temporary variables and references need copying */ - if (IS_UNUSED == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_UNUSED == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - - } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_UNUSED == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } - } - } - } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); - } - - /* Set the new yielded key */ - if (IS_CONST != IS_UNUSED) { - - zval *key = EX_CONSTANT(opline->op2); - - /* Consts, temporary variables and references need copying */ - if (IS_CONST == IS_CONST) { - ZVAL_COPY_VALUE(&generator->key, key); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->key))) { - Z_ADDREF(generator->key); - } - } else if (IS_CONST == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->key, key); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) { - ZVAL_COPY(&generator->key, Z_REFVAL_P(key)); - - } else { - ZVAL_COPY_VALUE(&generator->key, key); - if (IS_CONST == IS_CV) { - if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key); - } - } - - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); - } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); - } - - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; - } - - /* We increment to the next op, so we are at the correct position when the - * generator is resumed. */ - ZEND_VM_INC_OPCODE(); - - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - - ZEND_VM_RETURN(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -29041,14 +35862,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_UNUSED == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -29063,12 +35884,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_UNUSED == IS_CONST && IS_UNUSED == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { /* nothing to do */ } else if (IS_UNUSED != IS_CONST && IS_UNUSED == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); } else if (IS_UNUSED != IS_UNUSED) { @@ -29097,7 +35918,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { @@ -29461,7 +36282,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUS arg_count = EX_NUM_ARGS(); if (IS_UNUSED == IS_CONST) { - skip = Z_LVAL_P(EX_CONSTANT(opline->op1)); + skip = Z_LVAL_P(RT_CONSTANT(opline, opline->op1)); if (arg_count < skip) { result_size = 0; } else { @@ -29472,12 +36293,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUS result_size = arg_count; } - ht = (zend_array *) emalloc(sizeof(zend_array)); - zend_hash_init(ht, result_size, NULL, ZVAL_PTR_DTOR, 0); - ZVAL_ARR(EX_VAR(opline->result.var), ht); - if (result_size) { uint32_t first_extra_arg = EX(func)->op_array.num_args; + + ht = zend_new_array(result_size); + ZVAL_ARR(EX_VAR(opline->result.var), ht); zend_hash_real_init(ht, 1); ZEND_HASH_FILL_PACKED(ht) { zval *p, *q; @@ -29521,6 +36341,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUS } } ZEND_HASH_FILL_END(); ht->nNumOfElements = result_size; + } else { + ZVAL_EMPTY_ARRAY(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE(); } @@ -29544,7 +36366,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); do { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -29568,7 +36390,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); binary_op(zptr, zptr, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -29714,7 +36535,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); if (inc) { increment_function(zptr); @@ -29790,8 +36610,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } else { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); - zval_opt_copy_ctor(zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); if (inc) { increment_function(zptr); } else { @@ -29825,6 +36644,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HAN zval *container; zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); @@ -29833,18 +36653,25 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HAN ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_r_no_object; + do { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - } else { goto fetch_obj_r_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -29852,23 +36679,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HAN zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (IS_CV == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if (IS_CV == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } } } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (UNEXPECTED(zobj->handlers->read_property == NULL)) { @@ -29879,7 +36730,7 @@ fetch_obj_r_no_object: zend_string_release(property_name); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); @@ -29945,6 +36796,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HA zval *container; zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); @@ -29953,18 +36805,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HA ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); if (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_is_no_object; + do { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } } - } else { goto fetch_obj_is_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -29972,21 +36825,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HA zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (IS_CV == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if (IS_CV == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } } } } @@ -29996,7 +36871,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -30011,34 +36886,19 @@ fetch_obj_is_no_object: static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1; - zval *property; - - SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } @@ -30082,7 +36942,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - value = EX_CONSTANT((opline+1)->op1); + value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { do { @@ -30096,7 +36956,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -30128,11 +36988,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D if (IS_CV == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -30146,11 +37006,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -30169,24 +37029,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CONST == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -30254,7 +37110,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -30286,11 +37142,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D if (IS_CV == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -30304,11 +37160,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -30327,24 +37183,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_TMP_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -30412,7 +37264,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -30444,11 +37296,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D if (IS_CV == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -30462,11 +37314,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -30485,24 +37337,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -30570,7 +37418,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -30602,11 +37450,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D if (IS_CV == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -30620,11 +37468,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -30643,24 +37491,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CV == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CV == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -30711,7 +37555,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CV_HANDL rope = (zend_string**)EX_VAR(opline->result.var); if (IS_CV == IS_CONST) { var = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - rope[0] = zend_string_copy(Z_STR_P(var)); + rope[0] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); + } } else { var = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { @@ -30725,7 +37572,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_CV_HANDL if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { GET_OP2_UNDEF_CV(var, BP_VAR_R); } - rope[0] = _zval_get_string_func(var); + rope[0] = zval_get_string_func(var); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -30818,7 +37665,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C } /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); @@ -30844,7 +37691,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(obj)++; /* For $this pointer */ + GC_ADDREF(obj); /* For $this pointer */ } @@ -30873,14 +37720,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_UNUSED == IS_CONST) { /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce); } } else if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); @@ -30895,12 +37742,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (IS_UNUSED == IS_CONST && IS_CV == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { + EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) != NULL)) { /* nothing to do */ } else if (IS_UNUSED != IS_CONST && IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))) == ce)) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)) + sizeof(void*)); } else if (IS_CV != IS_UNUSED) { @@ -30929,7 +37776,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { @@ -31235,1587 +38082,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) -{ - USE_OPLINE - zend_free_op free_op2, free_op_data1; - zval *object; - zval *property; - zval *value; - zval *zptr; - - SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - do { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); - - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - ZVAL_DEREF(object); - if (UNEXPECTED(!make_real_object(object))) { - zend_string *property_name = zval_get_string(property); - zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - break; - } - } - - /* here we are sure we are dealing with an object */ - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); - - binary_op(zptr, zptr, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), zptr); - } - } - } else { - zend_assign_op_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - } - } while (0); - - FREE_OP(free_op_data1); - zval_ptr_dtor_nogc(free_op2); - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) -{ -#if 1 && (IS_TMP_VAR|IS_VAR) == IS_UNUSED - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -#else -# if 0 || IS_UNUSED != IS_UNUSED - USE_OPLINE - - if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_UNUSED_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } - if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } -# endif - - ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -#endif -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_TMPVAR_OBJ(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC) -{ - USE_OPLINE - zend_free_op free_op2; - zval *object; - zval *property; - zval *zptr; - - SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - do { - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - ZVAL_DEREF(object); - if (UNEXPECTED(!make_real_object(object))) { - zend_string *property_name = zval_get_string(property); - zend_error(E_WARNING, "Attempt to increment/decrement property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - break; - } - } - - /* here we are sure we are dealing with an object */ - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) { - if (inc) { - fast_long_increment_function(zptr); - } else { - fast_long_decrement_function(zptr); - } - } else { - ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); - - if (inc) { - increment_function(zptr); - } else { - decrement_function(zptr); - } - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), zptr); - } - } - } else { - zend_pre_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - } - } while (0); - - zval_ptr_dtor_nogc(free_op2); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC) -{ - USE_OPLINE - zend_free_op free_op2; - zval *object; - zval *property; - zval *zptr; - - SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - do { - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - ZVAL_DEREF(object); - if (UNEXPECTED(!make_real_object(object))) { - zend_string *property_name = zval_get_string(property); - zend_error(E_WARNING, "Attempt to increment/decrement property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - ZVAL_NULL(EX_VAR(opline->result.var)); - break; - } - } - - /* here we are sure we are dealing with an object */ - - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); - if (inc) { - fast_long_increment_function(zptr); - } else { - fast_long_decrement_function(zptr); - } - } else { - ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); - zval_opt_copy_ctor(zptr); - if (inc) { - increment_function(zptr); - } else { - decrement_function(zptr); - } - } - } - } else { - zend_post_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); - } - } while (0); - - zval_ptr_dtor_nogc(free_op2); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *container; - zend_free_op free_op2; - zval *offset; - - SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - if (IS_UNUSED == IS_CONST || - (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_r_no_object; - } - } else { - goto fetch_obj_r_no_object; - } - } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zval *retval; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } - } - - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { - zend_string *property_name; -fetch_obj_r_no_object: - property_name = zval_get_string(offset); - zend_error(E_NOTICE, "Trying to get property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - } - } - } while (0); - - zval_ptr_dtor_nogc(free_op2); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *property; - zval *container; - - SAVE_OPLINE(); - - container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - zval_ptr_dtor_nogc(free_op2); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *property; - zval *container; - - SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); - zval_ptr_dtor_nogc(free_op2); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *container; - zend_free_op free_op2; - zval *offset; - - SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - if (IS_UNUSED == IS_CONST || - (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_is_no_object; - } - } else { - goto fetch_obj_is_no_object; - } - } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zval *retval; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } - } - - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } - } - } while (0); - - zval_ptr_dtor_nogc(free_op2); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - - if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1, free_op2; - zval *property; - - SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) { - zend_throw_error(NULL, "Cannot use temporary expression in write context"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - zval_ptr_dtor_nogc(free_op2); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *container, *property; - - SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); - zval_ptr_dtor_nogc(free_op2); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *object, *property, *value, tmp; - - SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = EX_CONSTANT((opline+1)->op1); - - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - do { - if (Z_ISREF_P(object)) { - object = Z_REFVAL_P(object); - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - break; - } - } - if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE || - (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { - zend_object *obj; - - zval_ptr_dtor(object); - object_init(object); - Z_ADDREF_P(object); - obj = Z_OBJ_P(object); - zend_error(E_WARNING, "Creating default object from empty value"); - if (GC_REFCOUNT(obj) == 1) { - /* the enclosing container was deleted, obj is unreferenced */ - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - - OBJ_RELEASE(obj); - goto exit_assign_obj; - } - Z_DELREF_P(object); - } else { - if (IS_UNUSED != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { - zend_string *property_name = zval_get_string(property); - zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - - goto exit_assign_obj; - } - } while (0); - } - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); - zend_object *zobj = Z_OBJ_P(object); - zval *property_val; - - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { -fast_assign_obj: - value = zend_assign_to_variable(property_val, value, IS_CONST); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set) { - - if (EXPECTED(zobj->properties == NULL)) { - rebuild_object_properties(zobj); - } - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CONST != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CONST == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } - } else { - value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } - } else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, Z_STR_P(property), value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } - - if (!Z_OBJ_HT_P(object)->write_property) { - zend_string *property_name = zval_get_string(property); - zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - - goto exit_assign_obj; - } - - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); - } - - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - -exit_assign_obj: - zval_ptr_dtor_nogc(free_op2); - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2, free_op_data; - zval *object, *property, *value, tmp; - - SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); - - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - do { - if (Z_ISREF_P(object)) { - object = Z_REFVAL_P(object); - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - break; - } - } - if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE || - (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { - zend_object *obj; - - zval_ptr_dtor(object); - object_init(object); - Z_ADDREF_P(object); - obj = Z_OBJ_P(object); - zend_error(E_WARNING, "Creating default object from empty value"); - if (GC_REFCOUNT(obj) == 1) { - /* the enclosing container was deleted, obj is unreferenced */ - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - zval_ptr_dtor_nogc(free_op_data); - OBJ_RELEASE(obj); - goto exit_assign_obj; - } - Z_DELREF_P(object); - } else { - if (IS_UNUSED != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { - zend_string *property_name = zval_get_string(property); - zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - } while (0); - } - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); - zend_object *zobj = Z_OBJ_P(object); - zval *property_val; - - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { -fast_assign_obj: - value = zend_assign_to_variable(property_val, value, IS_TMP_VAR); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set) { - - if (EXPECTED(zobj->properties == NULL)) { - rebuild_object_properties(zobj); - } - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_TMP_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } - } else { - value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } - } else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, Z_STR_P(property), value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } - - if (!Z_OBJ_HT_P(object)->write_property) { - zend_string *property_name = zval_get_string(property); - zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(free_op_data); -exit_assign_obj: - zval_ptr_dtor_nogc(free_op2); - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2, free_op_data; - zval *object, *property, *value, tmp; - - SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = _get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); - - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - do { - if (Z_ISREF_P(object)) { - object = Z_REFVAL_P(object); - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - break; - } - } - if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE || - (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { - zend_object *obj; - - zval_ptr_dtor(object); - object_init(object); - Z_ADDREF_P(object); - obj = Z_OBJ_P(object); - zend_error(E_WARNING, "Creating default object from empty value"); - if (GC_REFCOUNT(obj) == 1) { - /* the enclosing container was deleted, obj is unreferenced */ - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - zval_ptr_dtor_nogc(free_op_data); - OBJ_RELEASE(obj); - goto exit_assign_obj; - } - Z_DELREF_P(object); - } else { - if (IS_UNUSED != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { - zend_string *property_name = zval_get_string(property); - zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - } while (0); - } - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); - zend_object *zobj = Z_OBJ_P(object); - zval *property_val; - - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { -fast_assign_obj: - value = zend_assign_to_variable(property_val, value, IS_VAR); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set) { - - if (EXPECTED(zobj->properties == NULL)) { - rebuild_object_properties(zobj); - } - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } - } else { - value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } - } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, Z_STR_P(property), value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } - - if (!Z_OBJ_HT_P(object)->write_property) { - zend_string *property_name = zval_get_string(property); - zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(free_op_data); -exit_assign_obj: - zval_ptr_dtor_nogc(free_op2); - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *object, *property, *value, tmp; - - SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - do { - if (Z_ISREF_P(object)) { - object = Z_REFVAL_P(object); - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - break; - } - } - if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE || - (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { - zend_object *obj; - - zval_ptr_dtor(object); - object_init(object); - Z_ADDREF_P(object); - obj = Z_OBJ_P(object); - zend_error(E_WARNING, "Creating default object from empty value"); - if (GC_REFCOUNT(obj) == 1) { - /* the enclosing container was deleted, obj is unreferenced */ - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - - OBJ_RELEASE(obj); - goto exit_assign_obj; - } - Z_DELREF_P(object); - } else { - if (IS_UNUSED != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) { - zend_string *property_name = zval_get_string(property); - zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - - goto exit_assign_obj; - } - } while (0); - } - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); - zend_object *zobj = Z_OBJ_P(object); - zval *property_val; - - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { -fast_assign_obj: - value = zend_assign_to_variable(property_val, value, IS_CV); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set) { - - if (EXPECTED(zobj->properties == NULL)) { - rebuild_object_properties(zobj); - } - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CV != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CV == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } - } else { - value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } - } else if (IS_CV == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, Z_STR_P(property), value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } - - if (!Z_OBJ_HT_P(object)->write_property) { - zend_string *property_name = zval_get_string(property); - zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - - goto exit_assign_obj; - } - - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); - } - - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - -exit_assign_obj: - zval_ptr_dtor_nogc(free_op2); - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zend_string **rope; - zval *var; - - /* Compiler allocates the necessary number of zval slots to keep the rope */ - rope = (zend_string**)EX_VAR(opline->result.var); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - var = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - rope[0] = zend_string_copy(Z_STR_P(var)); - } else { - var = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - rope[0] = zend_string_copy(Z_STR_P(var)); - } else { - rope[0] = Z_STR_P(var); - } - } else { - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(var, BP_VAR_R); - } - rope[0] = _zval_get_string_func(var); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *function_name; - zend_free_op free_op2; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; - - SAVE_OPLINE(); - - object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); - zval_ptr_dtor_nogc(free_op2); - - HANDLE_EXCEPTION(); - } while (0); - } - - if (IS_UNUSED != IS_UNUSED) { - do { - if (IS_UNUSED == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - break; - } - } - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = GET_OP1_UNDEF_CV(object, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - zval_ptr_dtor_nogc(free_op2); - - HANDLE_EXCEPTION(); - } - } while (0); - } - - obj = Z_OBJ_P(object); - called_scope = obj->ce; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); - } else { - zend_object *orig_obj = obj; - - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - zval_ptr_dtor_nogc(free_op2); - - HANDLE_EXCEPTION(); - } - - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); - } - zval_ptr_dtor_nogc(free_op2); - - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { - init_func_run_time_cache(&fbc->op_array); - } - } - - call_info = ZEND_CALL_NESTED_FUNCTION; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; - } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(obj)++; /* For $this pointer */ - } - - zval_ptr_dtor_nogc(free_op2); - - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *function_name; - zend_class_entry *ce; - zend_object *object; - zend_function *fbc; - zend_execute_data *call; - - SAVE_OPLINE(); - - if (IS_UNUSED == IS_CONST) { - /* no function found. try a static method in class */ - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); - } - } else if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - - if (IS_UNUSED == IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED((fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) != NULL)) { - /* nothing to do */ - } else if (IS_UNUSED != IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))) == ce)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)) + sizeof(void*)); - } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zend_free_op free_op2; - - function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Function name must be a string"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } while (0); - } - } - - if (ce->get_static_method) { - fbc = ce->get_static_method(ce, Z_STR_P(function_name)); - } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); - } - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), Z_STRVAL_P(function_name)); - } - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { - if (IS_UNUSED == IS_CONST) { - CACHE_PTR(Z_CACHE_SLOT_P(function_name), fbc); - } else { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), ce, fbc); - } - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { - init_func_run_time_cache(&fbc->op_array); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(free_op2); - } - } else { - if (UNEXPECTED(ce->constructor == NULL)) { - zend_throw_error(NULL, "Cannot call constructor"); - HANDLE_EXCEPTION(); - } - if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { - zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); - HANDLE_EXCEPTION(); - } - fbc = ce->constructor; - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { - init_func_run_time_cache(&fbc->op_array); - } - } - - object = NULL; - if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { - if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - object = Z_OBJ(EX(This)); - ce = object->ce; - } else { - if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - /* Allowed for PHP 4 compatibility. */ - zend_error( - E_DEPRECATED, - "Non-static method %s::%s() should not be called statically", - ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } else { - /* An internal function assumes $this is present and won't check that. - * So PHP would crash by allowing the call. */ - zend_throw_error( - zend_ce_error, - "Non-static method %s::%s() cannot be called statically", - ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); - HANDLE_EXCEPTION(); - } - } - } - - if (IS_UNUSED == IS_UNUSED) { - /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { - if (Z_TYPE(EX(This)) == IS_OBJECT) { - ce = Z_OBJCE(EX(This)); - } else { - ce = Z_CE(EX(This)); - } - } - } - - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, ce, object); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *container; - zval *offset; - - SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - do { - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (Z_TYPE_P(container) != IS_OBJECT) { - break; - } - } else { - break; - } - } - if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); - } else { - zend_string *property_name = zval_get_string(offset); - zend_error(E_NOTICE, "Trying to unset property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); - } - } while (0); - - zval_ptr_dtor_nogc(free_op2); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *container; - int result; - zval *offset; - - SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C); - - if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - if (IS_UNUSED == IS_CONST || - (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; - } - } else { - goto isset_no_object; - } - } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_string *property_name = zval_get_string(offset); - zend_error(E_NOTICE, "Trying to check property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); -isset_no_object: - result = ((opline->extended_value & ZEND_ISSET) == 0); - } else { - result = - ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); - } - - zval_ptr_dtor_nogc(free_op2); - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -32888,7 +38154,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_RETVAL_UNUSED_ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); increment_function(var_ptr); @@ -32927,7 +38192,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_RETVAL_USED_HA var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); increment_function(var_ptr); @@ -32966,7 +38230,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RETVAL_UNUSED_ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); decrement_function(var_ptr); @@ -33005,7 +38268,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RETVAL_USED_HA var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); decrement_function(var_ptr); @@ -33040,8 +38302,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - zval_opt_copy_ctor(var_ptr); + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); increment_function(var_ptr); @@ -33072,8 +38333,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); } ZVAL_DEREF(var_ptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - zval_opt_copy_ctor(var_ptr); + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); decrement_function(var_ptr); @@ -33096,7 +38356,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCO zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); } } else { - zend_string *str = _zval_get_string_func(z); + zend_string *str = zval_get_string_func(z); if (ZSTR_LEN(str) != 0) { zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); @@ -33330,7 +38590,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HAN retval_ptr = Z_REFVAL_P(retval_ptr); ZVAL_COPY_VALUE(return_value, retval_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { Z_ADDREF_P(retval_ptr); @@ -33368,7 +38628,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER( ZVAL_NEW_REF(EX(return_value), retval_ptr); if (IS_CV == IS_CONST) { - if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr); + Z_TRY_ADDREF_P(retval_ptr); } } break; @@ -33428,7 +38688,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_CV_HANDL retval = Z_REFVAL_P(retval); ZVAL_COPY_VALUE(&generator->retval, retval); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(retval)) { Z_ADDREF_P(retval); @@ -33476,7 +38736,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPC zend_exception_save(); if (IS_CV != IS_TMP_VAR) { - if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value); + Z_TRY_ADDREF_P(value); } zend_throw_exception_object(value); @@ -33511,7 +38771,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_H varptr = Z_REFVAL_P(varptr); ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(arg)) { Z_ADDREF_P(arg); @@ -33588,7 +38848,7 @@ send_var_by_ref: varptr = Z_REFVAL_P(varptr); ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(arg)) { Z_ADDREF_P(arg); @@ -33637,7 +38897,7 @@ send_var_by_ref: varptr = Z_REFVAL_P(varptr); ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(arg)) { Z_ADDREF_P(arg); @@ -33819,15 +39079,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO if (opline->extended_value == IS_ARRAY) { if (Z_TYPE_P(expr) != IS_OBJECT) { - ZVAL_NEW_ARR(result); - zend_hash_init(Z_ARRVAL_P(result), 8, NULL, ZVAL_PTR_DTOR, 0); if (Z_TYPE_P(expr) != IS_NULL) { + ZVAL_ARR(result, zend_new_array(8)); expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr); if (IS_CV == IS_CONST) { if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr); } else { if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); } + } else { + ZVAL_EMPTY_ARRAY(result); } } else { ZVAL_COPY_VALUE(result, expr); @@ -33951,7 +39212,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN if (Z_OBJ_P(array_ptr)->properties && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties)--; + GC_DELREF(Z_OBJ_P(array_ptr)->properties); } Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); } @@ -34054,6 +39315,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE } Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0); + if (IS_CV == IS_VAR) { + + } ZEND_VM_NEXT_OPCODE(); } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { if (!Z_OBJCE_P(array_ptr)->get_iterator) { @@ -34071,12 +39335,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE if (Z_OBJ_P(array_ptr)->properties && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties)--; + GC_DELREF(Z_OBJ_P(array_ptr)->properties); } Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); } Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0); + if (IS_CV == IS_VAR) { + + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { zend_class_entry *ce = Z_OBJCE_P(array_ptr); @@ -34221,7 +39488,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_O } else if (IS_CV == IS_VAR && ref) { zend_reference *r = Z_REF_P(ref); - if (UNEXPECTED(--GC_REFCOUNT(r) == 0)) { + if (UNEXPECTED(GC_DELREF(r) == 0)) { efree_size(r, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(result)) { Z_ADDREF_P(result); @@ -34261,7 +39528,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_ } else if (IS_CV == IS_VAR && ref) { zend_reference *r = Z_REF_P(ref); - if (UNEXPECTED(--GC_REFCOUNT(r) == 0)) { + if (UNEXPECTED(GC_DELREF(r) == 0)) { efree_size(r, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(result)) { Z_ADDREF_P(result); @@ -34474,26 +39741,37 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CV_HANDLER(ZEN int result = 0; - SAVE_OPLINE(); - value = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(value) == opline->extended_value)) { - if (UNEXPECTED(Z_TYPE_P(value) == IS_RESOURCE)) { - const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(value)); - - if (EXPECTED(type_name != NULL)) { - result = 1; - } - } else { + value = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + if ((1 << (uint32_t)Z_TYPE_P(value) & opline->extended_value)) { +type_check_resource: + if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE) + || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) { result = 1; } - } else if (UNEXPECTED(opline->extended_value == _IS_BOOL) && - EXPECTED(Z_TYPE_P(value) == IS_TRUE || Z_TYPE_P(value) == IS_FALSE)) { - result = 1; + } else if ((IS_CV & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + if ((1 << (uint32_t)Z_TYPE_P(value) & opline->extended_value)) { + goto type_check_resource; + } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + result = ((1 << IS_NULL) & opline->extended_value) != 0; + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(value, BP_VAR_R); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); + } } static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SIMPLE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -34577,7 +39855,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_CONST_HANDLER(ZEND zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { result = EX_VAR(opline->result.var); @@ -34620,7 +39898,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CV_CONST_HANDLER(ZEND zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { result = EX_VAR(opline->result.var); @@ -34663,7 +39941,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CV_CONST_HANDLER(ZEND zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { zend_long overflow; @@ -34710,7 +39988,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_CONST_HANDLER(ZEND SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); fast_div_function(EX_VAR(opline->result.var), op1, op2); @@ -34724,7 +40002,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CV_CONST_HANDLER(ZEND zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { result = EX_VAR(opline->result.var); @@ -34763,7 +40041,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_CONST_HANDLER(ZEND_ zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { @@ -34791,7 +40069,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CV_CONST_HANDLER(ZEND_ zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { @@ -34820,7 +40098,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_CONST_HANDLER(ZEND SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); pow_function(EX_VAR(opline->result.var), op1, op2); @@ -34834,7 +40112,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { @@ -34842,38 +40120,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z zend_string *op2_str = Z_STR_P(op2); zend_string *str; - do { - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - - break; - } - } - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - - break; - } + if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (IS_CV != IS_CONST && IS_CV != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; + } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - } while (0); + } else if (IS_CV != IS_CONST && IS_CV != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + + } ZEND_VM_NEXT_OPCODE(); } else { SAVE_OPLINE(); @@ -34900,7 +40176,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CONST_HAN SAVE_OPLINE(); op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); result = fast_is_identical_function(op1, op2); @@ -34918,7 +40194,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST SAVE_OPLINE(); op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); result = fast_is_not_identical_function(op1, op2); @@ -34934,7 +40210,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); do { int result; @@ -34956,17 +40232,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); } else { @@ -35002,7 +40268,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HAN zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); do { int result; @@ -35024,17 +40290,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HAN } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 0; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 1; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0); - } + result = !zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); } else { @@ -35070,7 +40326,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_CONST_HANDL zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); do { int result; @@ -35120,7 +40376,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CO zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); do { int result; @@ -35171,7 +40427,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_CONST_HANDLE SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); compare_function(EX_VAR(opline->result.var), op1, op2); @@ -35185,7 +40441,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CONST_HANDLER(ZE zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); @@ -35212,7 +40468,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_CONST_HANDLER(Z zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); @@ -35239,7 +40495,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_CONST_HANDLER(Z zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); @@ -35267,7 +40523,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); boolean_xor_function(EX_VAR(opline->result.var), op1, op2); @@ -35290,10 +40546,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); do { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -35317,7 +40573,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); binary_op(zptr, zptr, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -35350,6 +40605,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP assign_dim_op_array: SEPARATE_ARRAY(container); assign_dim_op_new_array: + dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_UNUSED) { var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { @@ -35357,8 +40613,6 @@ assign_dim_op_new_array: goto assign_dim_op_ret_null; } } else { - dim = EX_CONSTANT(opline->op2); - if (IS_CONST == IS_CONST) { var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); } else { @@ -35368,10 +40622,9 @@ assign_dim_op_new_array: goto assign_dim_op_ret_null; } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); binary_op(var_ptr, var_ptr, value); @@ -35387,15 +40640,14 @@ assign_dim_op_new_array: } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(container, zend_new_array(8)); goto assign_dim_op_new_array; } - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC); } else { if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { @@ -35417,7 +40669,7 @@ assign_dim_op_ret_null: ZVAL_NULL(EX_VAR(opline->result.var)); } } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); } } @@ -35434,7 +40686,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper zval *value; SAVE_OPLINE(); - value = EX_CONSTANT(opline->op2); + value = RT_CONSTANT(opline, opline->op2); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { @@ -35443,7 +40695,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper } } else { ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); binary_op(var_ptr, var_ptr, value); @@ -35711,7 +40962,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -35743,7 +40994,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); if (inc) { increment_function(zptr); @@ -35789,7 +41039,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -35819,8 +41069,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } else { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); - zval_opt_copy_ctor(zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); if (inc) { increment_function(zptr); } else { @@ -35857,7 +41106,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_ SAVE_OPLINE(); varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - retval = zend_fetch_static_property_address(varname, IS_CV, opline->op2, IS_CONST, type EXECUTE_DATA_CC); + retval = zend_fetch_static_property_address(varname, IS_CV, opline->op2, IS_CONST, type EXECUTE_DATA_CC OPLINE_CC); if (UNEXPECTED(retval == NULL)) { if (EG(exception)) { @@ -35922,7 +41171,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CONST_HAND SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); if (IS_CV != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_array: @@ -35959,7 +41208,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HAND SAVE_OPLINE(); container = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, RT_CONSTANT(opline, opline->op2), IS_CONST EXECUTE_DATA_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -35977,7 +41226,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HAN SAVE_OPLINE(); container = _get_zval_ptr_cv_undef_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); + zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, RT_CONSTANT(opline, opline->op2), IS_CONST EXECUTE_DATA_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -35994,7 +41243,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HAN SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, RT_CONSTANT(opline, opline->op2), IS_CONST EXECUTE_DATA_CC); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -36003,40 +41252,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HAN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zend_free_op free_op1; - - SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { if (IS_CONST == IS_UNUSED) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use [] for reading"); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); - - + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -36048,7 +41285,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_ SAVE_OPLINE(); container = _get_zval_ptr_cv_undef_BP_VAR_UNSET(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); + zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, RT_CONSTANT(opline, opline->op2), IS_CONST EXECUTE_DATA_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -36064,26 +41301,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HAND zval *container; zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); - container = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = EX_CONSTANT(opline->op2); + offset = RT_CONSTANT(opline, opline->op2); if (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_r_no_object; + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - } else { goto fetch_obj_r_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -36091,23 +41336,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HAND zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (IS_CONST == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if (IS_CONST == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } } } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (UNEXPECTED(zobj->handlers->read_property == NULL)) { @@ -36118,7 +41387,7 @@ fetch_obj_r_no_object: zend_string_release(property_name); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); @@ -36144,7 +41413,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HAND ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -36167,7 +41436,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HAN if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { @@ -36184,6 +41453,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HAN zval *container; zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); @@ -36192,18 +41462,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HAN ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = EX_CONSTANT(opline->op2); + offset = RT_CONSTANT(opline, opline->op2); if (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_is_no_object; + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } } - } else { goto fetch_obj_is_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -36211,21 +41482,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HAN zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (IS_CONST == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if (IS_CONST == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } } } } @@ -36235,7 +41528,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -36250,34 +41543,19 @@ fetch_obj_is_no_object: static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1; - zval *property; - - SAVE_OPLINE(); - container = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - property = EX_CONSTANT(opline->op2); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } @@ -36296,7 +41574,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_ ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); @@ -36307,7 +41585,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -36315,7 +41593,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_CONST_HANDL SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_LIST(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2) EXECUTE_DATA_CC); + zend_fetch_dimension_address_LIST_r(EX_VAR(opline->result.var), container, RT_CONSTANT(opline, opline->op2) EXECUTE_DATA_CC); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *retval, *container, *dim; + + SAVE_OPLINE(); + retval = EX_VAR(opline->result.var); + container = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + dim = RT_CONSTANT(opline, opline->op2); + + if (IS_CV == IS_VAR + && Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT + && UNEXPECTED(!Z_ISREF_P(container)) + ) { + zend_error(E_NOTICE, "Attempting to set reference to non referenceable value"); + zend_fetch_dimension_address_LIST_r(retval, container, dim EXECUTE_DATA_CC); + } else { + zend_fetch_dimension_address_LIST_w(retval, container, dim EXECUTE_DATA_CC); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -36333,8 +41635,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); - value = EX_CONSTANT((opline+1)->op1); + property = RT_CONSTANT(opline, opline->op2); + value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { do { @@ -36348,7 +41650,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -36380,11 +41682,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA if (IS_CONST == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -36398,11 +41700,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -36421,24 +41723,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CONST == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -36491,7 +41789,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -36506,7 +41804,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -36538,11 +41836,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA if (IS_CONST == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -36556,11 +41854,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -36579,24 +41877,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_TMP_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -36649,7 +41943,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -36664,7 +41958,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -36696,11 +41990,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA if (IS_CONST == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -36714,11 +42008,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -36737,24 +42031,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -36807,7 +42097,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = EX_CONSTANT(opline->op2); + property = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -36822,7 +42112,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -36854,11 +42144,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA if (IS_CONST == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -36872,11 +42162,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -36895,24 +42185,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CV == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CV == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -36975,7 +42261,7 @@ try_assign_dim_array: goto assign_dim_error; } } else { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { @@ -36985,7 +42271,7 @@ try_assign_dim_array: goto assign_dim_error; } } - value = EX_CONSTANT((opline+1)->op1); + value = RT_CONSTANT((opline+1), (opline+1)->op1); value = zend_assign_to_variable(variable_ptr, value, IS_CONST); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -36998,8 +42284,8 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = EX_CONSTANT(opline->op2); - value = EX_CONSTANT((opline+1)->op1); + dim = RT_CONSTANT(opline, opline->op2); + value = RT_CONSTANT((opline+1), (opline+1)->op1); zend_assign_to_object_dim(object_ptr, dim, value); @@ -37015,20 +42301,19 @@ try_assign_dim_array: UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = EX_CONSTANT(opline->op2); - value = EX_CONSTANT((opline+1)->op1); + dim = RT_CONSTANT(opline, opline->op2); + value = RT_CONSTANT((opline+1), (opline+1)->op1); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); assign_dim_error: if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -37067,7 +42352,7 @@ try_assign_dim_array: goto assign_dim_error; } } else { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { @@ -37090,7 +42375,7 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_object_dim(object_ptr, dim, value); @@ -37108,20 +42393,19 @@ try_assign_dim_array: UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); zval_ptr_dtor_nogc(free_op_data); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); assign_dim_error: zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -37160,7 +42444,7 @@ try_assign_dim_array: goto assign_dim_error; } } else { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { @@ -37183,7 +42467,7 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_object_dim(object_ptr, dim, value); @@ -37201,20 +42485,19 @@ try_assign_dim_array: UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); zval_ptr_dtor_nogc(free_op_data); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); assign_dim_error: zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -37253,7 +42536,7 @@ try_assign_dim_array: goto assign_dim_error; } } else { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { @@ -37276,7 +42559,7 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); zend_assign_to_object_dim(object_ptr, dim, value); @@ -37293,20 +42576,19 @@ try_assign_dim_array: UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); assign_dim_error: if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -37330,7 +42612,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UN zval *variable_ptr; SAVE_OPLINE(); - value = EX_CONSTANT(opline->op2); + value = RT_CONSTANT(opline, opline->op2); variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { @@ -37358,7 +42640,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_US zval *variable_ptr; SAVE_OPLINE(); - value = EX_CONSTANT(opline->op2); + value = RT_CONSTANT(opline, opline->op2); variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { @@ -37387,45 +42669,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HAND op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; - do { - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - - break; - } - } - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - - break; - } + if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (IS_CV != IS_CONST && IS_CV != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; + } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - } while (0); + } else if (IS_CV != IS_CONST && IS_CV != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + } ZEND_VM_NEXT_OPCODE(); } @@ -37438,7 +42718,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HAND if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - op1_str = _zval_get_string_func(op1); + op1_str = zval_get_string_func(op1); } if (IS_CONST == IS_CONST) { op2_str = Z_STR_P(op2); @@ -37448,13 +42728,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HAND if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { GET_OP2_UNDEF_CV(op2, BP_VAR_R); } - op2_str = _zval_get_string_func(op2); + op2_str = zval_get_string_func(op2); } do { if (IS_CV != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { if (IS_CONST == IS_CONST) { - zend_string_addref(op2_str); + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } } ZVAL_STR(EX_VAR(opline->result.var), op2_str); zend_string_release(op1_str); @@ -37464,7 +42746,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HAND if (IS_CONST != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { if (IS_CV == IS_CONST) { - zend_string_addref(op1_str); + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } } ZVAL_STR(EX_VAR(opline->result.var), op1_str); zend_string_release(op2_str); @@ -37507,7 +42791,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = EX_CONSTANT(opline->op2); + function_name = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -37572,7 +42856,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST } /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); @@ -37598,7 +42882,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(obj)++; /* For $this pointer */ + GC_ADDREF(obj); /* For $this pointer */ } @@ -37621,7 +42905,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEN zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); + op2 = RT_CONSTANT(opline, opline->op2); do { int result; @@ -37643,17 +42927,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEN } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); } else { break; @@ -37698,20 +42972,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONS if (IS_CV == IS_TMP_VAR) { /* pass */ } else if (IS_CV == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else if (IS_CV == IS_CV) { ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else /* if (IS_CV == IS_VAR) */ { if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { zend_refcounted *ref = Z_COUNTED_P(expr_ptr); expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; efree_size(ref, sizeof(zend_reference)); @@ -37724,7 +42994,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONS if (IS_CONST != IS_UNUSED) { - zval *offset = EX_CONSTANT(opline->op2); + zval *offset = RT_CONSTANT(opline, opline->op2); zend_string *str; zend_ulong hval; @@ -37763,13 +43033,13 @@ num_index: goto str_index; } else { zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -37784,26 +43054,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDL array = EX_VAR(opline->result.var); if (IS_CV != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - - if (IS_CV != IS_UNUSED) { + ZVAL_ARR(array, zend_new_array(size)); /* Explicitly initialize array as not-packed if flag is set */ if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init(Z_ARRVAL_P(array), 0); } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval tmp, *varname; + zval *varname; + zend_string *name, *tmp_name; zend_class_entry *ce; @@ -37811,35 +43078,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_CONS varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - ZVAL_UNDEF(&tmp); - if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); } - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; + name = zval_get_tmp_string(varname, &tmp_name); } if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); } } else if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } HANDLE_EXCEPTION(); @@ -37847,10 +43117,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_CONS } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); + zend_std_unset_static_property(ce, name); - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -37867,7 +43137,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLE SAVE_OPLINE(); container = _get_zval_ptr_cv_undef_BP_VAR_UNSET(opline->op1.var EXECUTE_DATA_CC); - offset = EX_CONSTANT(opline->op2); + offset = RT_CONSTANT(opline, opline->op2); do { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -37959,7 +43229,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLE if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = EX_CONSTANT(opline->op2); + offset = RT_CONSTANT(opline, opline->op2); do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { @@ -37991,20 +43261,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC zval *value; int result; - zval tmp, *varname; + zval *varname; + zend_string *name, *tmp_name; zend_class_entry *ce; SAVE_OPLINE(); varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); - ZVAL_UNDEF(&tmp); - if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); } if (IS_CONST == IS_CONST) { - if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -38012,22 +43283,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); } } else { if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op2.num); if (UNEXPECTED(ce == NULL)) { ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -38037,9 +43308,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC ce = Z_CE_P(EX_VAR(opline->op2.var)); } if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))) == ce)) { + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -38050,14 +43321,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC } } - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + value = zend_std_get_static_property(ce, name, 1); if (IS_CV == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); } - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } is_static_prop_return: @@ -38084,7 +43355,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_ SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - offset = EX_CONSTANT(opline->op2); + offset = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; @@ -38102,7 +43373,7 @@ isset_again: } } str_index_prop: - value = zend_hash_find_ind(ht, str); + value = zend_hash_find_ex_ind(ht, str, IS_CONST == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: @@ -38220,7 +43491,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = EX_CONSTANT(opline->op2); + offset = RT_CONSTANT(opline, opline->op2); if (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -38266,11 +43537,11 @@ try_instanceof: zend_class_entry *ce; if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); if (EXPECTED(ce)) { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); } } } else if (IS_CONST == IS_UNUSED) { @@ -38385,7 +43656,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE /* Set the new yielded key */ if (IS_CONST != IS_UNUSED) { - zval *key = EX_CONSTANT(opline->op2); + zval *key = RT_CONSTANT(opline, opline->op2); /* Consts, temporary variables and references need copying */ if (IS_CONST == IS_CONST) { @@ -38443,40 +43714,39 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_GLOBAL_SPEC_C zval *varname; zval *value; zval *variable_ptr; - uint32_t idx; + uintptr_t idx; zend_reference *ref; ZEND_VM_REPEATABLE_OPCODE - varname = EX_CONSTANT(opline->op2); + varname = RT_CONSTANT(opline, opline->op2); /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ - idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)) - 1; - if (EXPECTED(idx < EG(symbol_table).nNumUsed)) { - Bucket *p = EG(symbol_table).arData + idx; + idx = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)) - 1; + if (EXPECTED(idx < EG(symbol_table).nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)EG(symbol_table).arData + idx); if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && (EXPECTED(p->key == Z_STR_P(varname)) || (EXPECTED(p->h == ZSTR_H(Z_STR_P(varname))) && EXPECTED(p->key != NULL) && - EXPECTED(ZSTR_LEN(p->key) == Z_STRLEN_P(varname)) && - EXPECTED(memcmp(ZSTR_VAL(p->key), Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) { + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(varname)))))) { - value = &EG(symbol_table).arData[idx].val; + value = (zval*)p; /* value = &p->val; */ goto check_indirect; } } - value = zend_hash_find(&EG(symbol_table), Z_STR_P(varname)); + value = zend_hash_find_ex(&EG(symbol_table), Z_STR_P(varname), 1); if (UNEXPECTED(value == NULL)) { value = zend_hash_add_new(&EG(symbol_table), Z_STR_P(varname), &EG(uninitialized_zval)); - idx = ((char*)value - (char*)EG(symbol_table).arData) / sizeof(Bucket); + idx = (char*)value - (char*)EG(symbol_table).arData; /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1)); + CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(idx + 1)); } else { - idx = ((char*)value - (char*)EG(symbol_table).arData) / sizeof(Bucket); + idx = (char*)value - (char*)EG(symbol_table).arData; /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1)); + CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(idx + 1)); check_indirect: /* GLOBAL variable may be an INDIRECT pointer to CV */ if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { @@ -38489,21 +43759,21 @@ check_indirect: if (UNEXPECTED(!Z_ISREF_P(value))) { ref = (zend_reference*)emalloc(sizeof(zend_reference)); - GC_REFCOUNT(ref) = 2; + GC_SET_REFCOUNT(ref, 2); GC_TYPE_INFO(ref) = IS_REFERENCE; ZVAL_COPY_VALUE(&ref->val, value); Z_REF_P(value) = ref; Z_TYPE_INFO_P(value) = IS_REFERENCE_EX; } else { ref = Z_REF_P(value); - GC_REFCOUNT(ref)++; + GC_ADDREF(ref); } variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) { zend_refcounted *ref = Z_COUNTED_P(variable_ptr); - uint32_t refcnt = --GC_REFCOUNT(ref); + uint32_t refcnt = GC_DELREF(ref); if (EXPECTED(variable_ptr != value)) { if (refcnt == 0) { @@ -38540,16 +43810,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_CONST_HAND ZEND_ASSERT(ht != NULL); if (GC_REFCOUNT(ht) > 1) { if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_REFCOUNT(ht)--; + GC_DELREF(ht); } EX(func)->op_array.static_variables = ht = zend_array_dup(ht); } - varname = EX_CONSTANT(opline->op2); - value = zend_hash_find(ht, Z_STR_P(varname)); + varname = RT_CONSTANT(opline, opline->op2); + value = zend_hash_find_ex(ht, Z_STR_P(varname), 1); if (opline->extended_value) { - if (Z_CONSTANT_P(value)) { + if (Z_TYPE_P(value) == IS_CONSTANT_AST) { SAVE_OPLINE(); if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) { ZVAL_NULL(variable_ptr); @@ -38558,7 +43828,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_CONST_HAND } if (UNEXPECTED(!Z_ISREF_P(value))) { zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference)); - GC_REFCOUNT(ref) = 2; + GC_SET_REFCOUNT(ref, 2); GC_TYPE_INFO(ref) = IS_REFERENCE; ZVAL_COPY_VALUE(&ref->val, value); Z_REF_P(value) = ref; @@ -38583,7 +43853,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_CV_CONST_HAND HashTable *jumptable; op = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - jumptable = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); if (Z_TYPE_P(op) != IS_LONG) { ZVAL_DEREF(op); @@ -38612,17 +43882,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPEC_CV_CONST_HA HashTable *jumptable; op = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - jumptable = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); if (Z_TYPE_P(op) != IS_STRING) { - ZVAL_DEREF(op); - if (Z_TYPE_P(op) != IS_STRING) { + if (IS_CV == IS_CONST) { /* Wrong type, fall back to ZEND_CASE chain */ ZEND_VM_NEXT_OPCODE(); + } else { + ZVAL_DEREF(op); + if (Z_TYPE_P(op) != IS_STRING) { + /* Wrong type, fall back to ZEND_CASE chain */ + ZEND_VM_NEXT_OPCODE(); + } } } - jump_zv = zend_hash_find(jumptable, Z_STR_P(op)); + jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), IS_CV == IS_CONST); if (jump_zv != NULL) { ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); ZEND_VM_CONTINUE(); @@ -38638,7 +43913,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER USE_OPLINE zval *op1; - HashTable *ht = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); + HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); int result; SAVE_OPLINE(); @@ -38681,7 +43956,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_ zend_long offset; container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - dim = EX_CONSTANT(opline->op2); + dim = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_index_array: if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { @@ -38721,2380 +43996,14 @@ fetch_dim_r_index_undef: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(0)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR); - if (UNEXPECTED(0)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(1)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR); - if (UNEXPECTED(1)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - - SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - zend_throw_error(NULL, "Cannot yield from finally in a force-closed generator"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); - - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); - - /* Set the new yielded value */ - if (IS_CV != IS_UNUSED) { - - - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_CV & (IS_CONST|IS_TMP_VAR)) { - zval *value; - - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - - value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } - } else { - zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - if (IS_CV == IS_VAR && - (value_ptr == &EG(uninitialized_zval) || - (opline->extended_value == ZEND_RETURNS_FUNCTION && - !Z_ISREF_P(value_ptr)))) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - } else { - ZVAL_MAKE_REF(value_ptr); - } - ZVAL_COPY(&generator->value, value_ptr); - - } - } else { - zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - - /* Consts, temporary variables and references need copying */ - if (IS_CV == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_CV == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - - } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CV == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } - } - } - } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); - } - - /* Set the new yielded key */ - if (IS_TMP_VAR != IS_UNUSED) { - zend_free_op free_op2; - zval *key = _get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - /* Consts, temporary variables and references need copying */ - if (IS_TMP_VAR == IS_CONST) { - ZVAL_COPY_VALUE(&generator->key, key); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->key))) { - Z_ADDREF(generator->key); - } - } else if (IS_TMP_VAR == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->key, key); - } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) { - ZVAL_COPY(&generator->key, Z_REFVAL_P(key)); - - } else { - ZVAL_COPY_VALUE(&generator->key, key); - if (IS_TMP_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key); - } - } - - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); - } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); - } - - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; - } - - /* We increment to the next op, so we are at the correct position when the - * generator is resumed. */ - ZEND_VM_INC_OPCODE(); - - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - - ZEND_VM_RETURN(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_CV_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) -{ - USE_OPLINE - - zval *varname; - zval *retval; - - SAVE_OPLINE(); - varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - - retval = zend_fetch_static_property_address(varname, IS_CV, opline->op2, IS_VAR, type EXECUTE_DATA_CC); - - if (UNEXPECTED(retval == NULL)) { - if (EG(exception)) { - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } else { - ZEND_ASSERT(type == BP_VAR_IS); - retval = &EG(uninitialized_zval); - } - } - - if (type == BP_VAR_R || type == BP_VAR_IS) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - } else { - ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } else { - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(0)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_VAR); - if (UNEXPECTED(0)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { - zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(1)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_VAR); - if (UNEXPECTED(1)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op2; - zval *variable_ptr; - zval *value_ptr; - - SAVE_OPLINE(); - value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_VAR && - UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && - UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var))) && - UNEXPECTED(!Z_ISERROR_P(EX_VAR(opline->op1.var)))) { - - zend_throw_error(NULL, "Cannot assign by reference to overloaded object"); - - if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);}; - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - - } else if (IS_VAR == IS_VAR && - opline->extended_value == ZEND_RETURNS_FUNCTION && - UNEXPECTED(!Z_ISREF_P(value_ptr))) { - zend_error(E_NOTICE, "Only variables should be assigned by reference"); - if (UNEXPECTED(EG(exception) != NULL)) { - if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);}; - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - - value_ptr = zend_assign_to_variable(variable_ptr, value_ptr, IS_VAR); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value_ptr); - } - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - } else { - - if ((IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) || - (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr)))) { - variable_ptr = &EG(uninitialized_zval); - } else { - zend_assign_to_variable_reference(variable_ptr, value_ptr); - } - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); - } - - if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);}; - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval tmp, *varname; - zend_class_entry *ce; - - - SAVE_OPLINE(); - - varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - - ZVAL_UNDEF(&tmp); - if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - zend_std_unset_static_property(ce, Z_STR_P(varname)); - - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - int result; - - zval tmp, *varname; - zend_class_entry *ce; - - SAVE_OPLINE(); - varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); - ZVAL_UNDEF(&tmp); - if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_VAR == IS_CONST) { - if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))) == ce)) { - - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_static_prop_return; - } - } - - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if (IS_CV == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); - } - - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - -is_static_prop_return: - if (opline->extended_value & ZEND_ISSET) { - result = value && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = !value || !i_zend_is_true(value); - } - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *expr; - zend_bool result; - - SAVE_OPLINE(); - expr = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - -try_instanceof: - if (Z_TYPE_P(expr) == IS_OBJECT) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (EXPECTED(ce)) { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } - } else if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - result = ce && instanceof_function(Z_OBJCE_P(expr), ce); - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { - expr = Z_REFVAL_P(expr); - goto try_instanceof; - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { - GET_OP1_UNDEF_CV(expr, BP_VAR_R); - } - result = 0; - } - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - - SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - zend_throw_error(NULL, "Cannot yield from finally in a force-closed generator"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); - - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); - - /* Set the new yielded value */ - if (IS_CV != IS_UNUSED) { - - - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_CV & (IS_CONST|IS_TMP_VAR)) { - zval *value; - - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - - value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } - } else { - zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - if (IS_CV == IS_VAR && - (value_ptr == &EG(uninitialized_zval) || - (opline->extended_value == ZEND_RETURNS_FUNCTION && - !Z_ISREF_P(value_ptr)))) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - } else { - ZVAL_MAKE_REF(value_ptr); - } - ZVAL_COPY(&generator->value, value_ptr); - - } - } else { - zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - - /* Consts, temporary variables and references need copying */ - if (IS_CV == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_CV == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - - } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CV == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } - } - } - } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); - } - - /* Set the new yielded key */ - if (IS_VAR != IS_UNUSED) { - zend_free_op free_op2; - zval *key = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - /* Consts, temporary variables and references need copying */ - if (IS_VAR == IS_CONST) { - ZVAL_COPY_VALUE(&generator->key, key); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->key))) { - Z_ADDREF(generator->key); - } - } else if (IS_VAR == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->key, key); - } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) { - ZVAL_COPY(&generator->key, Z_REFVAL_P(key)); - zval_ptr_dtor_nogc(free_op2); - } else { - ZVAL_COPY_VALUE(&generator->key, key); - if (IS_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key); - } - } - - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); - } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); - } - - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; - } - - /* We increment to the next op, so we are at the correct position when the - * generator is resumed. */ - ZEND_VM_INC_OPCODE(); - - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - - ZEND_VM_RETURN(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) -{ - USE_OPLINE - zend_free_op free_op_data1; - zval *var_ptr; - zval *value, *container, *dim; - - SAVE_OPLINE(); - container = _get_zval_ptr_cv_undef_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -assign_dim_op_array: - SEPARATE_ARRAY(container); -assign_dim_op_new_array: - if (IS_UNUSED == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); - if (UNEXPECTED(!var_ptr)) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - goto assign_dim_op_ret_null; - } - } else { - dim = NULL; - - if (IS_UNUSED == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); - } else { - var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(!var_ptr)) { - goto assign_dim_op_ret_null; - } - ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); - } - - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); - - binary_op(var_ptr, var_ptr, value); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - } - } else { - if (EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto assign_dim_op_array; - } - } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { - container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); -assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); - goto assign_dim_op_new_array; - } - - dim = NULL; - - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); - zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC); - } else { - if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (IS_UNUSED == IS_UNUSED) { - zend_throw_error(NULL, "[] operator not supported for strings"); - } else { - zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC); - zend_wrong_string_offset(EXECUTE_DATA_C); - } - UNDEF_RESULT(); - } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - goto assign_dim_op_convert_to_array; - } else { - if (UNEXPECTED(IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(container)))) { - zend_error(E_WARNING, "Cannot use a scalar value as an array"); - } -assign_dim_op_ret_null: - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); - } - } - - FREE_OP(free_op_data1); - - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) -{ -#if 1 && IS_UNUSED == IS_UNUSED - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -#else -# if 0 || IS_CV != IS_UNUSED - USE_OPLINE - - if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_CV_UNUSED(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } - if (EXPECTED(1)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } -# endif - - ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -#endif -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type ZEND_OPCODE_HANDLER_ARGS_DC) -{ - USE_OPLINE - - zval *varname; - zval *retval; - zend_string *name; - HashTable *target_symbol_table; - - SAVE_OPLINE(); - varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - zend_string_addref(name); - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - name = zval_get_string(varname); - } - - target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { - if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { - zval *result; - -fetch_this: - result = EX_VAR(opline->result.var); - switch (type) { - case BP_VAR_R: - if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) { - ZVAL_OBJ(result, Z_OBJ(EX(This))); - Z_ADDREF_P(result); - } else { - ZVAL_NULL(result); - zend_error(E_NOTICE,"Undefined variable: this"); - } - break; - case BP_VAR_IS: - if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) { - ZVAL_OBJ(result, Z_OBJ(EX(This))); - Z_ADDREF_P(result); - } else { - ZVAL_NULL(result); - } - break; - case BP_VAR_RW: - case BP_VAR_W: - ZVAL_UNDEF(result); - zend_throw_error(NULL, "Cannot re-assign $this"); - break; - case BP_VAR_UNSET: - ZVAL_UNDEF(result); - zend_throw_error(NULL, "Cannot unset $this"); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - if (IS_CV != IS_CONST) { - zend_string_release(name); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); - break; - case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ - } else if (Z_TYPE_P(retval) == IS_INDIRECT) { - retval = Z_INDIRECT_P(retval); - if (Z_TYPE_P(retval) == IS_UNDEF) { - if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { - goto fetch_this; - } - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_W: - ZVAL_NULL(retval); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - } - } - - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - - } - - if (IS_CV != IS_CONST) { - zend_string_release(name); - } - - ZEND_ASSERT(retval != NULL); - if (type == BP_VAR_R || type == BP_VAR_IS) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - } else { - ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } else { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_CV_UNUSED(int type ZEND_OPCODE_HANDLER_ARGS_DC) -{ - USE_OPLINE - - zval *varname; - zval *retval; - - SAVE_OPLINE(); - varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - - retval = zend_fetch_static_property_address(varname, IS_CV, opline->op2, IS_UNUSED, type EXECUTE_DATA_CC); - - if (UNEXPECTED(retval == NULL)) { - if (EG(exception)) { - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } else { - ZEND_ASSERT(type == BP_VAR_IS); - retval = &EG(uninitialized_zval); - } - } - - if (type == BP_VAR_R || type == BP_VAR_IS) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - } else { - ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } else { - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - - SAVE_OPLINE(); - container = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED EXECUTE_DATA_CC); - - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - - SAVE_OPLINE(); - container = _get_zval_ptr_cv_undef_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); - - zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED EXECUTE_DATA_CC); - - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - zend_free_op free_op1; - - SAVE_OPLINE(); - - if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { - zend_throw_error(NULL, "Cannot use temporary expression in write context"); - - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - container = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED EXECUTE_DATA_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - - } else { - if (IS_UNUSED == IS_UNUSED) { - zend_throw_error(NULL, "Cannot use [] for reading"); - - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, NULL, IS_UNUSED EXECUTE_DATA_CC); - - - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *object_ptr; - - zval *value; - zval *variable_ptr; - zval *dim; - - SAVE_OPLINE(); - object_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_UNUSED == IS_UNUSED) { - variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); - if (UNEXPECTED(variable_ptr == NULL)) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - goto assign_dim_error; - } - } else { - dim = NULL; - if (IS_UNUSED == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - } - value = EX_CONSTANT((opline+1)->op1); - value = zend_assign_to_variable(variable_ptr, value, IS_CONST); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = NULL; - value = EX_CONSTANT((opline+1)->op1); - - zend_assign_to_object_dim(object_ptr, dim, value); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_UNUSED == IS_UNUSED) { - zend_throw_error(NULL, "[] operator not supported for strings"); - - - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else { - dim = NULL; - value = EX_CONSTANT((opline+1)->op1); - zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); - - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); - goto try_assign_dim_array; - } else { - if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { - zend_error(E_WARNING, "Cannot use a scalar value as an array"); - } - dim = NULL; -assign_dim_error: - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_UNUSED != IS_UNUSED) { - - } - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *object_ptr; - zend_free_op free_op_data; - zval *value; - zval *variable_ptr; - zval *dim; - - SAVE_OPLINE(); - object_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_UNUSED == IS_UNUSED) { - variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); - if (UNEXPECTED(variable_ptr == NULL)) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - goto assign_dim_error; - } - } else { - dim = NULL; - if (IS_UNUSED == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - } - value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); - value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = NULL; - value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); - - zend_assign_to_object_dim(object_ptr, dim, value); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - - zval_ptr_dtor_nogc(free_op_data); - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_UNUSED == IS_UNUSED) { - zend_throw_error(NULL, "[] operator not supported for strings"); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else { - dim = NULL; - value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); - goto try_assign_dim_array; - } else { - if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { - zend_error(E_WARNING, "Cannot use a scalar value as an array"); - } - dim = NULL; -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_UNUSED != IS_UNUSED) { - - } - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *object_ptr; - zend_free_op free_op_data; - zval *value; - zval *variable_ptr; - zval *dim; - - SAVE_OPLINE(); - object_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_UNUSED == IS_UNUSED) { - variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); - if (UNEXPECTED(variable_ptr == NULL)) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - goto assign_dim_error; - } - } else { - dim = NULL; - if (IS_UNUSED == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - } - value = _get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); - value = zend_assign_to_variable(variable_ptr, value, IS_VAR); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = NULL; - value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); - - zend_assign_to_object_dim(object_ptr, dim, value); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - - zval_ptr_dtor_nogc(free_op_data); - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_UNUSED == IS_UNUSED) { - zend_throw_error(NULL, "[] operator not supported for strings"); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else { - dim = NULL; - value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); - goto try_assign_dim_array; - } else { - if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { - zend_error(E_WARNING, "Cannot use a scalar value as an array"); - } - dim = NULL; -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_UNUSED != IS_UNUSED) { - - } - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *object_ptr; - - zval *value; - zval *variable_ptr; - zval *dim; - - SAVE_OPLINE(); - object_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_UNUSED == IS_UNUSED) { - variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); - if (UNEXPECTED(variable_ptr == NULL)) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - goto assign_dim_error; - } - } else { - dim = NULL; - if (IS_UNUSED == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - } - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable(variable_ptr, value, IS_CV); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = NULL; - value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - zend_assign_to_object_dim(object_ptr, dim, value); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_UNUSED == IS_UNUSED) { - zend_throw_error(NULL, "[] operator not supported for strings"); - - - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else { - dim = NULL; - value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); - - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); - goto try_assign_dim_array; - } else { - if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { - zend_error(E_WARNING, "Cannot use a scalar value as an array"); - } - dim = NULL; -assign_dim_error: - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_UNUSED != IS_UNUSED) { - - } - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - SAVE_OPLINE(); - if (IS_CV == IS_UNUSED) { - zend_verify_missing_return_type(EX(func), CACHE_ADDR(opline->op2.num)); - } else { -/* prevents "undefined variable opline" errors */ -#if 0 || (IS_CV != IS_UNUSED) - zval *retval_ref, *retval_ptr; - - zend_arg_info *ret_info = EX(func)->common.arg_info - 1; - - retval_ref = retval_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_CONST) { - ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr); - retval_ref = retval_ptr = EX_VAR(opline->result.var); - } else if (IS_CV == IS_VAR) { - if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) { - retval_ptr = Z_INDIRECT_P(retval_ptr); - } - ZVAL_DEREF(retval_ptr); - } else if (IS_CV == IS_CV) { - ZVAL_DEREF(retval_ptr); - } - - if (UNEXPECTED(!ZEND_TYPE_IS_CLASS(ret_info->type) - && ZEND_TYPE_CODE(ret_info->type) != IS_CALLABLE - && ZEND_TYPE_CODE(ret_info->type) != IS_ITERABLE - && !ZEND_SAME_FAKE_TYPE(ZEND_TYPE_CODE(ret_info->type), Z_TYPE_P(retval_ptr)) - && !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) - && retval_ref != retval_ptr) - ) { - /* A cast might happen - unwrap the reference if this is a by-value return */ - if (Z_REFCOUNT_P(retval_ref) == 1) { - ZVAL_UNREF(retval_ref); - } else { - Z_DELREF_P(retval_ref); - ZVAL_COPY(retval_ref, retval_ptr); - } - retval_ptr = retval_ref; - } - zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num)); -#endif - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *expr_ptr, new_expr; - - SAVE_OPLINE(); - if ((IS_CV == IS_VAR || IS_CV == IS_CV) && - UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - ZVAL_MAKE_REF(expr_ptr); - Z_ADDREF_P(expr_ptr); - - } else { - expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - if (IS_CV == IS_TMP_VAR) { - /* pass */ - } else if (IS_CV == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } else if (IS_CV == IS_CV) { - ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } else /* if (IS_CV == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(expr_ptr); - - expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { - ZVAL_COPY_VALUE(&new_expr, expr_ptr); - expr_ptr = &new_expr; - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } - } - } - - if (IS_UNUSED != IS_UNUSED) { - - zval *offset = NULL; - zend_string *str; - zend_ulong hval; - -add_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_UNUSED != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index; - } - } -str_index: - zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index: - zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto add_again; - } else if (Z_TYPE_P(offset) == IS_NULL) { - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval(Z_DVAL_P(offset)); - goto num_index; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index; - } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - GET_OP2_UNDEF_CV(offset, BP_VAR_R); - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else { - zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); - } - - } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); - } - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zval *array; - uint32_t size; - USE_OPLINE - - array = EX_VAR(opline->result.var); - if (IS_CV != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - - if (IS_CV != IS_UNUSED) { - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init(Z_ARRVAL_P(array), 0); - } - } - - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_CV_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var = EX_VAR(opline->op1.var); - - if (Z_REFCOUNTED_P(var)) { - zend_refcounted *garbage = Z_COUNTED_P(var); - - ZVAL_UNDEF(var); - SAVE_OPLINE(); - if (!--GC_REFCOUNT(garbage)) { - zval_dtor_func(garbage); - } else { - gc_check_possible_root(garbage); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZVAL_UNDEF(var); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval tmp, *varname; - HashTable *target_symbol_table; - - - SAVE_OPLINE(); - - varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - - ZVAL_UNDEF(&tmp); - if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); - - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval tmp, *varname; - zend_class_entry *ce; - - - SAVE_OPLINE(); - - varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - - ZVAL_UNDEF(&tmp); - if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - zend_std_unset_static_property(ce, Z_STR_P(varname)); - - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - int result; - - value = EX_VAR(opline->op1.var); - if (opline->extended_value & ZEND_ISSET) { - result = - Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - SAVE_OPLINE(); - result = !i_zend_is_true(value); - if (UNEXPECTED(EG(exception))) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_SET_NEXT_OPCODE(opline + 1); - ZEND_VM_CONTINUE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - int result; - - zval tmp, *varname; - HashTable *target_symbol_table; - - SAVE_OPLINE(); - varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); - ZVAL_UNDEF(&tmp); - if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); - - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - if (opline->extended_value & ZEND_ISSET) { - result = value && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = !value || !i_zend_is_true(value); - } - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - int result; - - zval tmp, *varname; - zend_class_entry *ce; - - SAVE_OPLINE(); - varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); - ZVAL_UNDEF(&tmp); - if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_UNUSED == IS_CONST) { - if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))) == ce)) { - - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_static_prop_return; - } - } - - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if (IS_CV == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); - } - - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - -is_static_prop_return: - if (opline->extended_value & ZEND_ISSET) { - result = value && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = !value || !i_zend_is_true(value); - } - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *expr; - zend_bool result; - - SAVE_OPLINE(); - expr = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - -try_instanceof: - if (Z_TYPE_P(expr) == IS_OBJECT) { - zend_class_entry *ce; - - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (EXPECTED(ce)) { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } - } else if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - result = ce && instanceof_function(Z_OBJCE_P(expr), ce); - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { - expr = Z_REFVAL_P(expr); - goto try_instanceof; - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { - GET_OP1_UNDEF_CV(expr, BP_VAR_R); - } - result = 0; - } - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - - SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - zend_throw_error(NULL, "Cannot yield from finally in a force-closed generator"); - - - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); - - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); - - /* Set the new yielded value */ - if (IS_CV != IS_UNUSED) { - - - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_CV & (IS_CONST|IS_TMP_VAR)) { - zval *value; - - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - - value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } - } else { - zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - if (IS_CV == IS_VAR && - (value_ptr == &EG(uninitialized_zval) || - (opline->extended_value == ZEND_RETURNS_FUNCTION && - !Z_ISREF_P(value_ptr)))) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - } else { - ZVAL_MAKE_REF(value_ptr); - } - ZVAL_COPY(&generator->value, value_ptr); - - } - } else { - zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - - /* Consts, temporary variables and references need copying */ - if (IS_CV == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_CV == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - - } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CV == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } - } - } - } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); - } - - /* Set the new yielded key */ - if (IS_UNUSED != IS_UNUSED) { - - zval *key = NULL; - - /* Consts, temporary variables and references need copying */ - if (IS_UNUSED == IS_CONST) { - ZVAL_COPY_VALUE(&generator->key, key); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->key))) { - Z_ADDREF(generator->key); - } - } else if (IS_UNUSED == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->key, key); - } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) { - ZVAL_COPY(&generator->key, Z_REFVAL_P(key)); - - } else { - ZVAL_COPY_VALUE(&generator->key, key); - if (IS_UNUSED == IS_CV) { - if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key); - } - } - - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); - } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); - } - - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; - } - - /* We increment to the next op, so we are at the correct position when the - * generator is resumed. */ - ZEND_VM_INC_OPCODE(); - - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - - ZEND_VM_RETURN(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1 = EX_VAR(opline->op1.var); - - if (UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(op1, BP_VAR_R); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MAKE_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1 = EX_VAR(opline->op1.var); - - if (IS_CV == IS_CV) { - if (UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_NEW_EMPTY_REF(op1); - Z_SET_REFCOUNT_P(op1, 2); - ZVAL_NULL(Z_REFVAL_P(op1)); - ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); - } else { - ZVAL_MAKE_REF(op1); - ZVAL_COPY(EX_VAR(opline->result.var), op1); - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_INDIRECT)) { - op1 = Z_INDIRECT_P(op1); - if (EXPECTED(!Z_ISREF_P(op1))) { - ZVAL_MAKE_REF(op1); - } - GC_REFCOUNT(Z_REF_P(op1))++; - ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), op1); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *op1; - zend_long count; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - do { - if (Z_TYPE_P(op1) == IS_ARRAY) { - count = zend_array_count(Z_ARRVAL_P(op1)); - break; - } else if (Z_TYPE_P(op1) == IS_OBJECT) { - /* first, we check if the handler is defined */ - if (Z_OBJ_HT_P(op1)->count_elements) { - if (SUCCESS == Z_OBJ_HT_P(op1)->count_elements(op1, &count)) { - break; - } - } - - /* if not and the object implements Countable we call its count() method */ - if (instanceof_function(Z_OBJCE_P(op1), zend_ce_countable)) { - zval retval; - - zend_call_method_with_0_params(op1, NULL, NULL, "count", &retval); - count = zval_get_long(&retval); - zval_ptr_dtor(&retval); - break; - } - - /* If There's no handler and it doesn't implement Countable then add a warning */ - count = 1; - } else if (Z_TYPE_P(op1) == IS_NULL) { - count = 0; - } else { - count = 1; - } - zend_error(E_WARNING, "count(): Parameter must be an array or an object that implements Countable"); - } while (0); - - ZVAL_LONG(EX_VAR(opline->result.var), count); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - if (IS_CV == IS_UNUSED) { - if (UNEXPECTED(!EX(func)->common.scope)) { - SAVE_OPLINE(); - zend_error(E_WARNING, "get_class() called without object from outside a class"); - ZVAL_FALSE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); - ZEND_VM_NEXT_OPCODE(); - } - } else { - - zval *op1; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - if (Z_TYPE_P(op1) == IS_OBJECT) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); - } else { - zend_error(E_WARNING, "get_class() expects parameter 1 to be object, %s given", zend_get_type_by_const(Z_TYPE_P(op1))); - ZVAL_FALSE(EX_VAR(opline->result.var)); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *op1; - zend_string *type; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - type = zend_zval_get_type(op1); - if (EXPECTED(type)) { - ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); - } else { - ZVAL_STRING(EX_VAR(opline->result.var), "unknown type"); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { result = EX_VAR(opline->result.var); @@ -41121,23 +44030,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_CV_HANDLER(ZEND_OP if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } add_function(EX_VAR(opline->result.var), op1, op2); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { result = EX_VAR(opline->result.var); @@ -41164,23 +44073,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CV_CV_HANDLER(ZEND_OP if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } sub_function(EX_VAR(opline->result.var), op1, op2); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { zend_long overflow; @@ -41210,38 +44119,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CV_CV_HANDLER(ZEND_OP if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } mul_function(EX_VAR(opline->result.var), op1, op2); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); fast_div_function(EX_VAR(opline->result.var), op1, op2); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { result = EX_VAR(opline->result.var); @@ -41264,23 +44173,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CV_CV_HANDLER(ZEND_OP if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } mod_function(EX_VAR(opline->result.var), op1, op2); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { @@ -41292,23 +44201,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_CV_HANDLER(ZEND_OPC if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } shift_left_function(EX_VAR(opline->result.var), op1, op2); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { @@ -41320,77 +44229,75 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CV_CV_HANDLER(ZEND_OPC if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } shift_right_function(EX_VAR(opline->result.var), op1, op2); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); pow_function(EX_VAR(opline->result.var), op1, op2); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; - do { - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - - break; - } - } - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - - break; - } + if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (IS_CV != IS_CONST && IS_CV != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } + zval_ptr_dtor_nogc(free_op2); + } else if (IS_CV != IS_CONST && IS_CV != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); - } while (0); + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + zval_ptr_dtor_nogc(free_op2); + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + zval_ptr_dtor_nogc(free_op2); + } ZEND_VM_NEXT_OPCODE(); } else { SAVE_OPLINE(); @@ -41398,60 +44305,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } concat_function(EX_VAR(opline->result.var), op1, op2); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *op1, *op2; - int result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { int result; @@ -41473,19 +44344,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZE } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } - + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + zval_ptr_dtor_nogc(free_op2); } else { break; } @@ -41501,25 +44362,25 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZE if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } result = EX_VAR(opline->result.var); compare_function(result, op1, op2); ZVAL_BOOL(result, Z_LVAL_P(result) == 0); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { int result; @@ -41541,19 +44402,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLE } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 0; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 1; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0); - } - + result = !zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + zval_ptr_dtor_nogc(free_op2); } else { break; } @@ -41569,25 +44420,25 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLE if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } result = EX_VAR(opline->result.var); compare_function(result, op1, op2); ZVAL_BOOL(result, Z_LVAL_P(result) != 0); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { int result; @@ -41619,25 +44470,25 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_CV_HANDLER( if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } result = EX_VAR(opline->result.var); compare_function(result, op1, op2); ZVAL_BOOL(result, Z_LVAL_P(result) < 0); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { int result; @@ -41669,40 +44520,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CV if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } result = EX_VAR(opline->result.var); compare_function(result, op1, op2); ZVAL_BOOL(result, Z_LVAL_P(result) <= 0); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); compare_function(EX_VAR(opline->result.var), op1, op2); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); @@ -41713,23 +44564,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CV_HANDLER(ZEND_ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } bitwise_or_function(EX_VAR(opline->result.var), op1, op2); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); @@ -41740,23 +44591,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_CV_HANDLER(ZEND if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } bitwise_and_function(EX_VAR(opline->result.var), op1, op2); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); @@ -41767,34 +44618,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_CV_HANDLER(ZEND if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } bitwise_xor_function(EX_VAR(opline->result.var), op1, op2); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); boolean_xor_function(EX_VAR(opline->result.var), op1, op2); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - zend_free_op free_op_data1; + zend_free_op free_op2, free_op_data1; zval *object; zval *property; zval *value; @@ -41807,10 +44658,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -41827,14 +44678,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); binary_op(zptr, zptr, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -41842,21 +44692,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } } else { - zend_assign_op_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_assign_op_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); FREE_OP(free_op_data1); - + zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - zend_free_op free_op_data1; + zend_free_op free_op2, free_op_data1; zval *var_ptr; zval *value, *container, *dim; @@ -41867,16 +44717,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP assign_dim_op_array: SEPARATE_ARRAY(container); assign_dim_op_new_array: - if (IS_CV == IS_UNUSED) { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); goto assign_dim_op_ret_null; } } else { - dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - - if (IS_CV == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); } else { var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); @@ -41885,10 +44734,9 @@ assign_dim_op_new_array: goto assign_dim_op_ret_null; } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); binary_op(var_ptr, var_ptr, value); @@ -41904,19 +44752,18 @@ assign_dim_op_new_array: } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(container, zend_new_array(8)); goto assign_dim_op_new_array; } - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC); } else { if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if (IS_CV == IS_UNUSED) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC); @@ -41934,24 +44781,25 @@ assign_dim_op_ret_null: ZVAL_NULL(EX_VAR(opline->result.var)); } } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); } } + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper_SPEC_CV_CV(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper_SPEC_CV_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zend_free_op free_op2; zval *var_ptr; zval *value; SAVE_OPLINE(); - value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + value = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { @@ -41960,7 +44808,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper } } else { ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); binary_op(var_ptr, var_ptr, value); @@ -41969,254 +44816,255 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper } } + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_CV_CV(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_CV_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { -#if 1 && IS_CV == IS_UNUSED - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#if 1 && (IS_TMP_VAR|IS_VAR) == IS_UNUSED + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #else # if 0 || IS_CV != IS_UNUSED USE_OPLINE if (EXPECTED(1)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } # endif - ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #endif } -static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_CV_CV_DIM(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { -#if 1 && IS_CV == IS_UNUSED - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#if 1 && (IS_TMP_VAR|IS_VAR) == IS_UNUSED + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #else # if 0 || IS_CV != IS_UNUSED USE_OPLINE if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } if (EXPECTED(1)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } # endif - ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #endif } -static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { -#if 1 && IS_CV == IS_UNUSED - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#if 1 && (IS_TMP_VAR|IS_VAR) == IS_UNUSED + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #else # if 0 || IS_CV != IS_UNUSED USE_OPLINE if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } # endif - ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #endif } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(int inc ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zend_free_op free_op2; zval *object; zval *property; zval *zptr; @@ -42228,7 +45076,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -42246,7 +45094,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -42260,7 +45108,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); if (inc) { increment_function(zptr); @@ -42273,28 +45120,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } } else { - zend_pre_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_pre_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_CV_CV(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_CV_CV(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(int inc ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - + zend_free_op free_op2; zval *object; zval *property; zval *zptr; @@ -42306,7 +45154,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -42323,7 +45171,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -42336,8 +45184,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } else { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); - zval_opt_copy_ctor(zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); if (inc) { increment_function(zptr); } else { @@ -42346,37 +45193,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } } else { - zend_post_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); + zend_post_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); } } while (0); + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_CV_CV(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_CV_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_CV_CV(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_CV_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *container, *dim, *value, *result; SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (IS_CV != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC); + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); ZVAL_COPY_UNREF(result, value); } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { @@ -42393,24 +45241,24 @@ fetch_dim_r_slow: } } else { result = EX_VAR(opline->result.var); - zend_fetch_dimension_address_read_R(result, container, dim, IS_CV EXECUTE_DATA_CC); + zend_fetch_dimension_address_read_R(result, container, dim, (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); } - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1; + zend_free_op free_op1, free_op2; zval *container; SAVE_OPLINE(); container = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); - + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -42418,17 +45266,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1; + zend_free_op free_op1, free_op2; zval *container; SAVE_OPLINE(); container = _get_zval_ptr_cv_undef_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); - + zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -42436,70 +45284,58 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *container; SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); - + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zend_free_op free_op1; - - SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - - + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if (IS_CV == IS_UNUSED) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use [] for reading"); - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); - - + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1; + zend_free_op free_op1, free_op2; zval *container; SAVE_OPLINE(); container = _get_zval_ptr_cv_undef_BP_VAR_UNSET(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); - + zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -42507,33 +45343,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HAN ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; - + zend_free_op free_op2; zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); - container = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_r_no_object; + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - } else { goto fetch_obj_r_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -42541,23 +45385,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (IS_CV == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } } } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (UNEXPECTED(zobj->handlers->read_property == NULL)) { @@ -42568,7 +45436,7 @@ fetch_obj_r_no_object: zend_string_release(property_name); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); @@ -42576,14 +45444,15 @@ fetch_obj_r_no_object: } } while (0); + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1; + zend_free_op free_op1, free_op2; zval *property; zval *container; @@ -42594,9 +45463,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -42604,10 +45473,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1; + zend_free_op free_op1, free_op2; zval *property; zval *container; @@ -42617,9 +45486,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLE if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); - + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -42627,13 +45496,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; - + zend_free_op free_op2; zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); @@ -42642,18 +45512,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLE ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_is_no_object; + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } } - } else { goto fetch_obj_is_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -42661,21 +45532,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLE zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (IS_CV == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } } } } @@ -42685,7 +45578,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -42693,50 +45586,36 @@ fetch_obj_is_no_object: } } while (0); + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1; - zval *property; - - SAVE_OPLINE(); - container = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1; + zend_free_op free_op1, free_op2; zval *container, *property; SAVE_OPLINE(); @@ -42746,10 +45625,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HAN ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -42757,23 +45636,48 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HAN ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *container; SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_LIST(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC) EXECUTE_DATA_CC); - + zend_fetch_dimension_address_LIST_r(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zend_free_op free_op2; + zval *retval, *container, *dim; + SAVE_OPLINE(); + retval = EX_VAR(opline->result.var); + container = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + if (IS_CV == IS_VAR + && Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT + && UNEXPECTED(!Z_ISREF_P(container)) + ) { + zend_error(E_NOTICE, "Attempting to set reference to non referenceable value"); + zend_fetch_dimension_address_LIST_r(retval, container, dim EXECUTE_DATA_CC); + } else { + zend_fetch_dimension_address_LIST_w(retval, container, dim EXECUTE_DATA_CC); + } + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -42783,8 +45687,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - value = EX_CONSTANT((opline+1)->op1); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { do { @@ -42798,7 +45702,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -42828,13 +45732,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } while (0); } - if (IS_CV == IS_CONST && + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -42848,11 +45752,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -42871,24 +45775,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CONST == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -42915,23 +45815,23 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } exit_assign_obj: - + zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op_data; + zend_free_op free_op2, free_op_data; zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -42941,7 +45841,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -42956,7 +45856,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -42986,13 +45886,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } while (0); } - if (IS_CV == IS_CONST && + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -43006,11 +45906,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -43029,24 +45929,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_TMP_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -43073,23 +45969,23 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); exit_assign_obj: - + zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op_data; + zend_free_op free_op2, free_op_data; zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -43099,7 +45995,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); value = _get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -43114,7 +46010,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -43144,13 +46040,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } while (0); } - if (IS_CV == IS_CONST && + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -43164,11 +46060,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -43187,24 +46083,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -43231,23 +46123,23 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); exit_assign_obj: - + zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -43257,7 +46149,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -43272,7 +46164,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -43302,13 +46194,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } while (0); } - if (IS_CV == IS_CONST && + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -43322,11 +46214,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -43345,24 +46237,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CV == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CV == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -43389,25 +46277,25 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } exit_assign_obj: - + zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr; - + zend_free_op free_op2; zval *value; zval *variable_ptr; zval *dim; @@ -43418,15 +46306,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if (IS_CV == IS_UNUSED) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); if (UNEXPECTED(variable_ptr == NULL)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); goto assign_dim_error; } } else { - dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (IS_CV == IS_CONST) { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -43435,7 +46323,7 @@ try_assign_dim_array: goto assign_dim_error; } } - value = EX_CONSTANT((opline+1)->op1); + value = RT_CONSTANT((opline+1), (opline+1)->op1); value = zend_assign_to_variable(variable_ptr, value, IS_CONST); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -43448,8 +46336,8 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - value = EX_CONSTANT((opline+1)->op1); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = RT_CONSTANT((opline+1), (opline+1)->op1); zend_assign_to_object_dim(object_ptr, dim, value); @@ -43458,27 +46346,26 @@ try_assign_dim_array: } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CV == IS_UNUSED) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - value = EX_CONSTANT((opline+1)->op1); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = RT_CONSTANT((opline+1), (opline+1)->op1); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); assign_dim_error: if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -43486,20 +46373,20 @@ assign_dim_error: } } } - if (IS_CV != IS_UNUSED) { - + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zval_ptr_dtor_nogc(free_op2); } /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr; - zend_free_op free_op_data; + zend_free_op free_op2, free_op_data; zval *value; zval *variable_ptr; zval *dim; @@ -43510,15 +46397,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if (IS_CV == IS_UNUSED) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); if (UNEXPECTED(variable_ptr == NULL)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); goto assign_dim_error; } } else { - dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (IS_CV == IS_CONST) { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -43540,7 +46427,7 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_object_dim(object_ptr, dim, value); @@ -43551,27 +46438,26 @@ try_assign_dim_array: zval_ptr_dtor_nogc(free_op_data); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CV == IS_UNUSED) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); zval_ptr_dtor_nogc(free_op_data); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); assign_dim_error: zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -43579,20 +46465,20 @@ assign_dim_error: } } } - if (IS_CV != IS_UNUSED) { - + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zval_ptr_dtor_nogc(free_op2); } /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr; - zend_free_op free_op_data; + zend_free_op free_op2, free_op_data; zval *value; zval *variable_ptr; zval *dim; @@ -43603,15 +46489,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if (IS_CV == IS_UNUSED) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); if (UNEXPECTED(variable_ptr == NULL)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); goto assign_dim_error; } } else { - dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (IS_CV == IS_CONST) { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -43633,7 +46519,7 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_object_dim(object_ptr, dim, value); @@ -43644,27 +46530,26 @@ try_assign_dim_array: zval_ptr_dtor_nogc(free_op_data); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CV == IS_UNUSED) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); zval_ptr_dtor_nogc(free_op_data); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); assign_dim_error: zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -43672,20 +46557,20 @@ assign_dim_error: } } } - if (IS_CV != IS_UNUSED) { - + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zval_ptr_dtor_nogc(free_op2); } /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr; - + zend_free_op free_op2; zval *value; zval *variable_ptr; zval *dim; @@ -43696,15 +46581,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if (IS_CV == IS_UNUSED) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); if (UNEXPECTED(variable_ptr == NULL)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); goto assign_dim_error; } } else { - dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (IS_CV == IS_CONST) { + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -43726,7 +46611,7 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); zend_assign_to_object_dim(object_ptr, dim, value); @@ -43736,27 +46621,26 @@ try_assign_dim_array: } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CV == IS_UNUSED) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); assign_dim_error: if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -43764,174 +46648,60 @@ assign_dim_error: } } } - if (IS_CV != IS_UNUSED) { - + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zval_ptr_dtor_nogc(free_op2); } /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { - - if (UNEXPECTED(0)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_CV); - if (UNEXPECTED(0)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { - - if (UNEXPECTED(1)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_CV); - if (UNEXPECTED(1)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *variable_ptr; - zval *value_ptr; - - SAVE_OPLINE(); - value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_VAR && - UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && - UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var))) && - UNEXPECTED(!Z_ISERROR_P(EX_VAR(opline->op1.var)))) { - - zend_throw_error(NULL, "Cannot assign by reference to overloaded object"); - - - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - - } else if (IS_CV == IS_VAR && - opline->extended_value == ZEND_RETURNS_FUNCTION && - UNEXPECTED(!Z_ISREF_P(value_ptr))) { - zend_error(E_NOTICE, "Only variables should be assigned by reference"); - if (UNEXPECTED(EG(exception) != NULL)) { - - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - - value_ptr = zend_assign_to_variable(variable_ptr, value_ptr, IS_CV); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value_ptr); - } - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - } else { - - if ((IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) || - (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr)))) { - variable_ptr = &EG(uninitialized_zval); - } else { - zend_assign_to_variable_reference(variable_ptr, value_ptr); - } - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); - } - - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2; zend_string *op1_str, *op2_str, *str; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; - do { - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - - break; - } - } - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - - break; - } + if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (IS_CV != IS_CONST && IS_CV != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } + zval_ptr_dtor_nogc(free_op2); + } else if (IS_CV != IS_CONST && IS_CV != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); - } while (0); + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + zval_ptr_dtor_nogc(free_op2); + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + zval_ptr_dtor_nogc(free_op2); + } ZEND_VM_NEXT_OPCODE(); } @@ -43944,33 +46714,37 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - op1_str = _zval_get_string_func(op1); + op1_str = zval_get_string_func(op1); } - if (IS_CV == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { op2_str = Z_STR_P(op2); } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { op2_str = zend_string_copy(Z_STR_P(op2)); } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { GET_OP2_UNDEF_CV(op2, BP_VAR_R); } - op2_str = _zval_get_string_func(op2); + op2_str = zval_get_string_func(op2); } do { if (IS_CV != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CV == IS_CONST) { - zend_string_addref(op2_str); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } } ZVAL_STR(EX_VAR(opline->result.var), op2_str); zend_string_release(op1_str); break; } } - if (IS_CV != IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { if (IS_CV == IS_CONST) { - zend_string_addref(op1_str); + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } } ZVAL_STR(EX_VAR(opline->result.var), op1_str); zend_string_release(op2_str); @@ -43984,20 +46758,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER if (IS_CV != IS_CONST) { zend_string_release(op1_str); } - if (IS_CV != IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_string_release(op2_str); } } while (0); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; - + zend_free_op free_op2; zval *object; zend_function *fbc; zend_class_entry *called_scope; @@ -44013,17 +46787,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (IS_CV != IS_CONST && + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { GET_OP2_UNDEF_CV(function_name, BP_VAR_R); if (UNEXPECTED(EG(exception) != NULL)) { @@ -44031,7 +46805,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA } } zend_throw_error(NULL, "Method name must be a string"); - + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } while (0); @@ -44049,12 +46823,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { object = GET_OP1_UNDEF_CV(object, BP_VAR_R); if (UNEXPECTED(EG(exception) != NULL)) { - + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } @@ -44064,7 +46838,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA obj = Z_OBJ_P(object); called_scope = obj->ce; - if (IS_CV == IS_CONST && + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); } else { @@ -44072,22 +46846,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA if (UNEXPECTED(obj->handlers->get_method == NULL)) { zend_throw_error(NULL, "Object does not support method calls"); - + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); } - + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_CV == IS_CONST && + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { @@ -44104,9 +46878,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(obj)++; /* For $this pointer */ + GC_ADDREF(obj); /* For $this pointer */ } + zval_ptr_dtor_nogc(free_op2); if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -44120,14 +46895,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { int result; @@ -44149,18 +46924,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_O } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } - + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + zval_ptr_dtor_nogc(free_op2); } else { break; } @@ -44176,17 +46941,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_O if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } result = EX_VAR(opline->result.var); compare_function(result, op1, op2); ZVAL_BOOL(result, Z_LVAL_P(result) == 0); - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -44204,20 +46969,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_H if (IS_CV == IS_TMP_VAR) { /* pass */ } else if (IS_CV == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else if (IS_CV == IS_CV) { ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else /* if (IS_CV == IS_VAR) */ { if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { zend_refcounted *ref = Z_COUNTED_P(expr_ptr); expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; efree_size(ref, sizeof(zend_reference)); @@ -44228,16 +46989,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_H } } - if (IS_CV != IS_UNUSED) { - - zval *offset = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zend_free_op free_op2; + zval *offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); zend_string *str; zend_ulong hval; add_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if (IS_CV != IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index; } @@ -44248,7 +47009,7 @@ str_index: hval = Z_LVAL_P(offset); num_index: zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { offset = Z_REFVAL_P(offset); goto add_again; } else if (Z_TYPE_P(offset) == IS_NULL) { @@ -44263,25 +47024,25 @@ num_index: } else if (Z_TYPE_P(offset) == IS_TRUE) { hval = 1; goto num_index; - } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); str = ZSTR_EMPTY_ALLOC(); goto str_index; } else { zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } - + zval_ptr_dtor_nogc(free_op2); } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *array; uint32_t size; @@ -44290,26 +47051,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER( array = EX_VAR(opline->result.var); if (IS_CV != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - - if (IS_CV != IS_UNUSED) { + ZVAL_ARR(array, zend_new_array(size)); /* Explicitly initialize array as not-packed if flag is set */ if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init(Z_ARRVAL_P(array), 0); } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *container; zval *offset; zend_ulong hval; @@ -44317,7 +47074,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(Z SAVE_OPLINE(); container = _get_zval_ptr_cv_undef_BP_VAR_UNSET(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -44329,7 +47086,7 @@ unset_dim_array: offset_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { key = Z_STR_P(offset); - if (IS_CV != IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { if (ZEND_HANDLE_NUMERIC(key, hval)) { goto num_index_dim; } @@ -44344,7 +47101,7 @@ str_index_dim: hval = Z_LVAL_P(offset); num_index_dim: zend_hash_index_del(ht, hval); - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { offset = Z_REFVAL_P(offset); goto offset_again; } else if (Z_TYPE_P(offset) == IS_DOUBLE) { @@ -44362,7 +47119,7 @@ num_index_dim: } else if (Z_TYPE_P(offset) == IS_RESOURCE) { hval = Z_RES_HANDLE_P(offset); goto num_index_dim; - } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); key = ZSTR_EMPTY_ALLOC(); goto str_index_dim; @@ -44379,7 +47136,7 @@ num_index_dim: if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_R); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { @@ -44393,14 +47150,15 @@ num_index_dim: } } while (0); + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *container; zval *offset; @@ -44409,7 +47167,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(Z if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { @@ -44423,7 +47181,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(Z } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } else { zend_string *property_name = zval_get_string(offset); zend_error(E_NOTICE, "Trying to unset property '%s' of non-object", ZSTR_VAL(property_name)); @@ -44431,14 +47189,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(Z } } while (0); + zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *container; int result; zend_ulong hval; @@ -44446,7 +47205,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_ SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; @@ -44458,18 +47217,18 @@ isset_dim_obj_array: isset_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if (IS_CV != IS_CONST) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index_prop; } } str_index_prop: - value = zend_hash_find_ind(ht, str); + value = zend_hash_find_ex_ind(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: value = zend_hash_index_find(ht, hval); - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { offset = Z_REFVAL_P(offset); goto isset_again; } else if (Z_TYPE_P(offset) == IS_DOUBLE) { @@ -44487,7 +47246,7 @@ num_index_prop: } else if (Z_TYPE_P(offset) == IS_RESOURCE) { hval = Z_RES_HANDLE_P(offset); goto num_index_prop; - } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); str = ZSTR_EMPTY_ALLOC(); goto str_index_prop; @@ -44511,7 +47270,7 @@ num_index_prop: } } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); } @@ -44543,7 +47302,7 @@ isset_str_offset: goto isset_not_found; } } else { - if (IS_CV & (IS_CV|IS_VAR)) { + if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -44560,17 +47319,17 @@ isset_not_found: } isset_dim_obj_exit: - + zval_ptr_dtor_nogc(free_op2); ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - + zend_free_op free_op2; zval *container; int result; zval *offset; @@ -44582,7 +47341,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); if (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -44604,16 +47363,157 @@ isset_no_object: } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } + zval_ptr_dtor_nogc(free_op2); ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *container, *dim, *value; + zend_long offset; + + container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + offset = zval_get_long(dim); + } + ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim EXECUTE_DATA_CC); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2; + int result; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + result = fast_is_identical_function(op1, op2); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2; + int result; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + result = fast_is_not_identical_function(op1, op2); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + value = _get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(0)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR); + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + /* zend_assign_to_variable() always takes care of op2, never free it! */ + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + value = _get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(1)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR); + if (UNEXPECTED(1)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + /* zend_assign_to_variable() always takes care of op2, never free it! */ + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -44622,7 +47522,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_ SAVE_OPLINE(); if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { zend_throw_error(NULL, "Cannot yield from finally in a force-closed generator"); - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); UNDEF_RESULT(); HANDLE_EXCEPTION(); @@ -44696,24 +47596,574 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_ } /* Set the new yielded key */ + if (IS_TMP_VAR != IS_UNUSED) { + zend_free_op free_op2; + zval *key = _get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + + /* Consts, temporary variables and references need copying */ + if (IS_TMP_VAR == IS_CONST) { + ZVAL_COPY_VALUE(&generator->key, key); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->key))) { + Z_ADDREF(generator->key); + } + } else if (IS_TMP_VAR == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->key, key); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) { + ZVAL_COPY(&generator->key, Z_REFVAL_P(key)); + + } else { + ZVAL_COPY_VALUE(&generator->key, key); + if (IS_TMP_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key); + } + } + + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); + } + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + } + + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; + } + + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); + + ZEND_VM_RETURN(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2; + int result; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var_deref(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + result = fast_is_identical_function(op1, op2); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *op1, *op2; + int result; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_var_deref(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + result = fast_is_not_identical_function(op1, op2); + + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_CV_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) +{ + USE_OPLINE + + zval *varname; + zval *retval; + + SAVE_OPLINE(); + varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + + retval = zend_fetch_static_property_address(varname, IS_CV, opline->op2, IS_VAR, type EXECUTE_DATA_CC OPLINE_CC); + + if (UNEXPECTED(retval == NULL)) { + if (EG(exception)) { + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } else { + ZEND_ASSERT(type == BP_VAR_IS); + retval = &EG(uninitialized_zval); + } + } + + if (type == BP_VAR_R || type == BP_VAR_IS) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + } else { + ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } else { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + value = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(0)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_VAR); + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + /* zend_assign_to_variable() always takes care of op2, never free it! */ + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + value = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { + zval_ptr_dtor_nogc(free_op2); + if (UNEXPECTED(1)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_VAR); + if (UNEXPECTED(1)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + /* zend_assign_to_variable() always takes care of op2, never free it! */ + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *variable_ptr; + zval *value_ptr; + + SAVE_OPLINE(); + value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV == IS_VAR && + UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && + UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var))) && + UNEXPECTED(!Z_ISERROR_P(EX_VAR(opline->op1.var)))) { + + zend_throw_error(NULL, "Cannot assign by reference to overloaded object"); + + if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);}; + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + + } else if (IS_VAR == IS_VAR && + opline->extended_value == ZEND_RETURNS_FUNCTION && + UNEXPECTED(!Z_ISREF_P(value_ptr))) { + zend_error(E_NOTICE, "Only variables should be assigned by reference"); + if (UNEXPECTED(EG(exception) != NULL)) { + if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);}; + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + + value_ptr = zend_assign_to_variable(variable_ptr, value_ptr, IS_VAR); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value_ptr); + } + /* zend_assign_to_variable() always takes care of op2, never free it! */ + + } else { + + if ((IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) || + (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr)))) { + variable_ptr = &EG(uninitialized_zval); + } else { + zend_assign_to_variable_reference(variable_ptr, value_ptr); + } + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); + } + + if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);}; + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varname; + zend_string *name, *tmp_name; + zend_class_entry *ce; + + + SAVE_OPLINE(); + + varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + if (IS_VAR == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + zend_std_unset_static_property(ce, name); + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + int result; + + zval *varname; + zend_string *name, *tmp_name; + zend_class_entry *ce; + + SAVE_OPLINE(); + varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + + if (IS_VAR == IS_CONST) { + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + goto is_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + } + } else { + if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { + + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + goto is_static_prop_return; + } + } + + value = zend_std_get_static_property(ce, name, 1); + + if (IS_CV == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); + } + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + +is_static_prop_return: + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *expr; + zend_bool result; + + SAVE_OPLINE(); + expr = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; + + if (IS_VAR == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (EXPECTED(ce)) { + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + } + } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(expr, BP_VAR_R); + } + result = 0; + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + + SAVE_OPLINE(); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + zend_throw_error(NULL, "Cannot yield from finally in a force-closed generator"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); + + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); + + /* Set the new yielded value */ if (IS_CV != IS_UNUSED) { - zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_CV & (IS_CONST|IS_TMP_VAR)) { + zval *value; + + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + + value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } + } else { + zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + if (IS_CV == IS_VAR && + (value_ptr == &EG(uninitialized_zval) || + (opline->extended_value == ZEND_RETURNS_FUNCTION && + !Z_ISREF_P(value_ptr)))) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } else { + ZVAL_MAKE_REF(value_ptr); + } + ZVAL_COPY(&generator->value, value_ptr); + + } + } else { + zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + + /* Consts, temporary variables and references need copying */ + if (IS_CV == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } else if (IS_CV == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + + } else { + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CV == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } + } + } + } else { + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); + } + + /* Set the new yielded key */ + if (IS_VAR != IS_UNUSED) { + zend_free_op free_op2; + zval *key = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); /* Consts, temporary variables and references need copying */ - if (IS_CV == IS_CONST) { + if (IS_VAR == IS_CONST) { ZVAL_COPY_VALUE(&generator->key, key); if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->key))) { Z_ADDREF(generator->key); } - } else if (IS_CV == IS_TMP_VAR) { + } else if (IS_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(&generator->key, key); - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) { + } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) { ZVAL_COPY(&generator->key, Z_REFVAL_P(key)); - + zval_ptr_dtor_nogc(free_op2); } else { ZVAL_COPY_VALUE(&generator->key, key); - if (IS_CV == IS_CV) { + if (IS_VAR == IS_CV) { if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key); } } @@ -44749,62 +48199,1590 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_ ZEND_VM_RETURN(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE + zend_free_op free_op_data1; + zval *var_ptr; + zval *value, *container, *dim; - zval *container, *dim, *value; - zend_long offset; + SAVE_OPLINE(); + container = _get_zval_ptr_cv_undef_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); - container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_index_array: - if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { - offset = Z_LVAL_P(dim); +assign_dim_op_array: + SEPARATE_ARRAY(container); +assign_dim_op_new_array: + dim = NULL; + if (IS_UNUSED == IS_UNUSED) { + var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); + if (UNEXPECTED(!var_ptr)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + goto assign_dim_op_ret_null; + } } else { - offset = zval_get_long(dim); + if (IS_UNUSED == IS_CONST) { + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + } else { + var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(!var_ptr)) { + goto assign_dim_op_ret_null; + } + ZVAL_DEREF(var_ptr); } - ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - SAVE_OPLINE(); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + + binary_op(var_ptr, var_ptr, value); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + } + } else { + if (EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto assign_dim_op_array; + } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { + container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); +assign_dim_op_convert_to_array: + ZVAL_ARR(container, zend_new_array(8)); + goto assign_dim_op_new_array; + } + + dim = NULL; + + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC); + } else { + if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { + if (IS_UNUSED == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + } else { + zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC); + zend_wrong_string_offset(EXECUTE_DATA_C); + } + UNDEF_RESULT(); + } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + goto assign_dim_op_convert_to_array; + } else { + if (UNEXPECTED(IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(container)))) { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); + } +assign_dim_op_ret_null: + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + } + } + + FREE_OP(free_op_data1); + + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +{ +#if 1 && IS_UNUSED == IS_UNUSED + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#else +# if 0 || IS_CV != IS_UNUSED + USE_OPLINE + + if (EXPECTED(0)) { + ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_CV_UNUSED(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } + if (EXPECTED(1)) { + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } +# endif + + ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#endif +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_UNUSED_DIM(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type ZEND_OPCODE_HANDLER_ARGS_DC) +{ + USE_OPLINE + + zval *varname; + zval *retval; + zend_string *name, *tmp_name; + HashTable *target_symbol_table; + + SAVE_OPLINE(); + varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); + retval = zend_hash_find_ex(target_symbol_table, name, IS_CV == IS_CONST); + if (retval == NULL) { + if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { + zval *result; + +fetch_this: + result = EX_VAR(opline->result.var); + switch (type) { + case BP_VAR_R: + if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) { + ZVAL_OBJ(result, Z_OBJ(EX(This))); + Z_ADDREF_P(result); + } else { + ZVAL_NULL(result); + zend_error(E_NOTICE,"Undefined variable: this"); + } + break; + case BP_VAR_IS: + if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) { + ZVAL_OBJ(result, Z_OBJ(EX(This))); + Z_ADDREF_P(result); + } else { + ZVAL_NULL(result); + } + break; + case BP_VAR_RW: + case BP_VAR_W: + ZVAL_UNDEF(result); + zend_throw_error(NULL, "Cannot re-assign $this"); + break; + case BP_VAR_UNSET: + ZVAL_UNDEF(result); + zend_throw_error(NULL, "Cannot unset $this"); + break; + EMPTY_SWITCH_DEFAULT_CASE() + } + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + switch (type) { + case BP_VAR_R: + case BP_VAR_UNSET: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + /* break missing intentionally */ + case BP_VAR_IS: + retval = &EG(uninitialized_zval); + break; + case BP_VAR_RW: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); + break; + case BP_VAR_W: + retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + break; + EMPTY_SWITCH_DEFAULT_CASE() + } + /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ + } else if (Z_TYPE_P(retval) == IS_INDIRECT) { + retval = Z_INDIRECT_P(retval); + if (Z_TYPE_P(retval) == IS_UNDEF) { + if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { + goto fetch_this; + } + switch (type) { + case BP_VAR_R: + case BP_VAR_UNSET: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + /* break missing intentionally */ + case BP_VAR_IS: + retval = &EG(uninitialized_zval); + break; + case BP_VAR_RW: + zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); + /* break missing intentionally */ + case BP_VAR_W: + ZVAL_NULL(retval); + break; + EMPTY_SWITCH_DEFAULT_CASE() + } + } + } + + if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + + } + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + ZEND_ASSERT(retval != NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + } else { + ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } else { + ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_CV_UNUSED(int type ZEND_OPCODE_HANDLER_ARGS_DC) +{ + USE_OPLINE + + zval *varname; + zval *retval; + + SAVE_OPLINE(); + varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + + retval = zend_fetch_static_property_address(varname, IS_CV, opline->op2, IS_UNUSED, type EXECUTE_DATA_CC OPLINE_CC); + + if (UNEXPECTED(retval == NULL)) { + if (EG(exception)) { + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } else { - ZEND_VM_NEXT_OPCODE(); + ZEND_ASSERT(type == BP_VAR_IS); + retval = &EG(uninitialized_zval); } - } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_index_array; + } + + if (type == BP_VAR_R || type == BP_VAR_IS) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + } else { + ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } else { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container; + + SAVE_OPLINE(); + container = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED EXECUTE_DATA_CC); + + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container; + + SAVE_OPLINE(); + container = _get_zval_ptr_cv_undef_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); + + zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED EXECUTE_DATA_CC); + + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use temporary expression in write context"); + + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_UNUSED == IS_UNUSED) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use [] for reading"); + + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *object_ptr; + + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_UNUSED == IS_UNUSED) { + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + goto assign_dim_error; + } } else { - goto fetch_dim_r_index_slow; + dim = NULL; + if (IS_UNUSED == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + } + value = RT_CONSTANT((opline+1), (opline+1)->op1); + value = zend_assign_to_variable(variable_ptr, value, IS_CONST); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); } } else { -fetch_dim_r_index_slow: + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + dim = NULL; + value = RT_CONSTANT((opline+1), (opline+1)->op1); + + zend_assign_to_object_dim(object_ptr, dim, value); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_UNUSED == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else { + dim = NULL; + value = RT_CONSTANT((opline+1), (opline+1)->op1); + zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); + + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + ZVAL_ARR(object_ptr, zend_new_array(8)); + goto try_assign_dim_array; + } else { + if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); + } + dim = NULL; +assign_dim_error: + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + if (IS_UNUSED != IS_UNUSED) { + + } + + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *object_ptr; + zend_free_op free_op_data; + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_UNUSED == IS_UNUSED) { + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + goto assign_dim_error; + } + } else { + dim = NULL; + if (IS_UNUSED == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + } + value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + dim = NULL; + value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + + zend_assign_to_object_dim(object_ptr, dim, value); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + zval_ptr_dtor_nogc(free_op_data); + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_UNUSED == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else { + dim = NULL; + value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op_data); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + ZVAL_ARR(object_ptr, zend_new_array(8)); + goto try_assign_dim_array; + } else { + if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); + } + dim = NULL; +assign_dim_error: + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + if (IS_UNUSED != IS_UNUSED) { + + } + + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *object_ptr; + zend_free_op free_op_data; + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_UNUSED == IS_UNUSED) { + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + goto assign_dim_error; + } + } else { + dim = NULL; + if (IS_UNUSED == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + } + value = _get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + value = zend_assign_to_variable(variable_ptr, value, IS_VAR); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + dim = NULL; + value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + + zend_assign_to_object_dim(object_ptr, dim, value); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + zval_ptr_dtor_nogc(free_op_data); + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_UNUSED == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else { + dim = NULL; + value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); + zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(free_op_data); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + ZVAL_ARR(object_ptr, zend_new_array(8)); + goto try_assign_dim_array; + } else { + if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); + } + dim = NULL; +assign_dim_error: + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + if (IS_UNUSED != IS_UNUSED) { + + } + + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *object_ptr; + + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_UNUSED == IS_UNUSED) { + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + goto assign_dim_error; + } + } else { + dim = NULL; + if (IS_UNUSED == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + } + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable(variable_ptr, value, IS_CV); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + dim = NULL; + value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + + zend_assign_to_object_dim(object_ptr, dim, value); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_UNUSED == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else { + dim = NULL; + value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); + + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + ZVAL_ARR(object_ptr, zend_new_array(8)); + goto try_assign_dim_array; + } else { + if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); + } + dim = NULL; +assign_dim_error: + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + if (IS_UNUSED != IS_UNUSED) { + + } + + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + SAVE_OPLINE(); + if (IS_CV == IS_UNUSED) { + zend_verify_missing_return_type(EX(func), CACHE_ADDR(opline->op2.num)); + } else { +/* prevents "undefined variable opline" errors */ +#if 0 || (IS_CV != IS_UNUSED) + zval *retval_ref, *retval_ptr; + + zend_arg_info *ret_info = EX(func)->common.arg_info - 1; + + retval_ref = retval_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV == IS_CONST) { + ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr); + retval_ref = retval_ptr = EX_VAR(opline->result.var); + } else if (IS_CV == IS_VAR) { + if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) { + retval_ptr = Z_INDIRECT_P(retval_ptr); + } + ZVAL_DEREF(retval_ptr); + } else if (IS_CV == IS_CV) { + ZVAL_DEREF(retval_ptr); + } + + if (UNEXPECTED(!ZEND_TYPE_IS_CLASS(ret_info->type) + && ZEND_TYPE_CODE(ret_info->type) != IS_CALLABLE + && ZEND_TYPE_CODE(ret_info->type) != IS_ITERABLE + && !ZEND_SAME_FAKE_TYPE(ZEND_TYPE_CODE(ret_info->type), Z_TYPE_P(retval_ptr)) + && !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) + && retval_ref != retval_ptr) + ) { + /* A cast might happen - unwrap the reference if this is a by-value return */ + if (Z_REFCOUNT_P(retval_ref) == 1) { + ZVAL_UNREF(retval_ref); + } else { + Z_DELREF_P(retval_ref); + ZVAL_COPY(retval_ref, retval_ptr); + } + retval_ptr = retval_ref; + } + zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num)); +#endif + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *expr_ptr, new_expr; + + SAVE_OPLINE(); + if ((IS_CV == IS_VAR || IS_CV == IS_CV) && + UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { + expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + ZVAL_MAKE_REF(expr_ptr); + Z_ADDREF_P(expr_ptr); + + } else { + expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_TMP_VAR) { + /* pass */ + } else if (IS_CV == IS_CONST) { + Z_TRY_ADDREF_P(expr_ptr); + } else if (IS_CV == IS_CV) { + ZVAL_DEREF(expr_ptr); + Z_TRY_ADDREF_P(expr_ptr); + } else /* if (IS_CV == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(expr_ptr); + + expr_ptr = Z_REFVAL_P(expr_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + ZVAL_COPY_VALUE(&new_expr, expr_ptr); + expr_ptr = &new_expr; + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } + } + } + } + + if (IS_UNUSED != IS_UNUSED) { + + zval *offset = NULL; + zend_string *str; + zend_ulong hval; + +add_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_UNUSED != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index; + } + } +str_index: + zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index: + zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); + } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto add_again; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index; + } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else { + zend_error(E_WARNING, "Illegal offset type"); + zval_ptr_dtor_nogc(expr_ptr); + } + + } else { + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + zval_ptr_dtor_nogc(expr_ptr); + } + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zval *array; + uint32_t size; + USE_OPLINE + + array = EX_VAR(opline->result.var); + if (IS_CV != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init(Z_ARRVAL_P(array), 0); + } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_CV_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var = EX_VAR(opline->op1.var); + + if (Z_REFCOUNTED_P(var)) { + zend_refcounted *garbage = Z_COUNTED_P(var); + + ZVAL_UNDEF(var); SAVE_OPLINE(); - zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim EXECUTE_DATA_CC); + if (!GC_DELREF(garbage)) { + zval_dtor_func(garbage); + } else { + gc_check_possible_root(garbage); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZVAL_UNDEF(var); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varname; + zend_string *name, *tmp_name; + HashTable *target_symbol_table; + + + SAVE_OPLINE(); + + varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); + zend_hash_del_ind(target_symbol_table, name); + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varname; + zend_string *name, *tmp_name; + zend_class_entry *ce; + + + SAVE_OPLINE(); + + varname = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); + } + name = zval_get_tmp_string(varname, &tmp_name); + } + + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + zend_std_unset_static_property(ce, name); + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + int result; + + value = EX_VAR(opline->op1.var); + if (opline->extended_value & ZEND_ISSET) { + result = + Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + SAVE_OPLINE(); + result = !i_zend_is_true(value); + if (UNEXPECTED(EG(exception))) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_SET_NEXT_OPCODE(opline + 1); + ZEND_VM_CONTINUE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + int result; + + zval *varname; + zend_string *name, *tmp_name; + HashTable *target_symbol_table; + + SAVE_OPLINE(); + varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + + target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); + value = zend_hash_find_ex_ind(target_symbol_table, name, IS_CV == IS_CONST); + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + int result; + + zval *varname; + zend_string *name, *tmp_name; + zend_class_entry *ce; + + SAVE_OPLINE(); + varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + + if (IS_UNUSED == IS_CONST) { + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)))) != NULL)) { + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + goto is_static_prop_return; + } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)))) == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + } + } else { + if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1))) == ce)) { + + value = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)) + sizeof(void*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + goto is_static_prop_return; + } + } + + value = zend_std_get_static_property(ce, name, 1); + + if (IS_CV == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), ce, value); + } + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + +is_static_prop_return: + if (opline->extended_value & ZEND_ISSET) { + result = value && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { + result = !value || !i_zend_is_true(value); + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *expr; + zend_bool result; + + SAVE_OPLINE(); + expr = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); + +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; + + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2))); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), RT_CONSTANT(opline, opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (EXPECTED(ce)) { + CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op2)), ce); + } + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(expr, BP_VAR_R); + } + result = 0; + } + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + + SAVE_OPLINE(); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + zend_throw_error(NULL, "Cannot yield from finally in a force-closed generator"); + + + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); + + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); + + /* Set the new yielded value */ + if (IS_CV != IS_UNUSED) { + + + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_CV & (IS_CONST|IS_TMP_VAR)) { + zval *value; + + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + + value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } + } else { + zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + if (IS_CV == IS_VAR && + (value_ptr == &EG(uninitialized_zval) || + (opline->extended_value == ZEND_RETURNS_FUNCTION && + !Z_ISREF_P(value_ptr)))) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + } else { + ZVAL_MAKE_REF(value_ptr); + } + ZVAL_COPY(&generator->value, value_ptr); + + } + } else { + zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + + /* Consts, temporary variables and references need copying */ + if (IS_CV == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } else if (IS_CV == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + + } else { + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CV == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } + } + } + } else { + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); + } + + /* Set the new yielded key */ + if (IS_UNUSED != IS_UNUSED) { + + zval *key = NULL; + + /* Consts, temporary variables and references need copying */ + if (IS_UNUSED == IS_CONST) { + ZVAL_COPY_VALUE(&generator->key, key); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->key))) { + Z_ADDREF(generator->key); + } + } else if (IS_UNUSED == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->key, key); + } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) { + ZVAL_COPY(&generator->key, Z_REFVAL_P(key)); + + } else { + ZVAL_COPY_VALUE(&generator->key, key); + if (IS_UNUSED == IS_CV) { + if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key); + } + } + + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); + } + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + } + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; + } + + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); + + ZEND_VM_RETURN(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1 = EX_VAR(opline->op1.var); + + if (UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(op1, BP_VAR_R); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MAKE_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1 = EX_VAR(opline->op1.var); + + if (IS_CV == IS_CV) { + if (UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_NEW_EMPTY_REF(op1); + Z_SET_REFCOUNT_P(op1, 2); + ZVAL_NULL(Z_REFVAL_P(op1)); + ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); + } else { + ZVAL_MAKE_REF(op1); + ZVAL_COPY(EX_VAR(opline->result.var), op1); + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_INDIRECT)) { + op1 = Z_INDIRECT_P(op1); + if (EXPECTED(!Z_ISREF_P(op1))) { + ZVAL_MAKE_REF(op1); + } + GC_ADDREF(Z_REF_P(op1)); + ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); + } else { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), op1); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *op1; + zend_long count; -fetch_dim_r_index_undef: - ZVAL_NULL(EX_VAR(opline->result.var)); SAVE_OPLINE(); - zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + do { + if (Z_TYPE_P(op1) == IS_ARRAY) { + count = zend_array_count(Z_ARRVAL_P(op1)); + break; + } else if (Z_TYPE_P(op1) == IS_OBJECT) { + /* first, we check if the handler is defined */ + if (Z_OBJ_HT_P(op1)->count_elements) { + if (SUCCESS == Z_OBJ_HT_P(op1)->count_elements(op1, &count)) { + break; + } + } + + /* if not and the object implements Countable we call its count() method */ + if (instanceof_function(Z_OBJCE_P(op1), zend_ce_countable)) { + zval retval; + + zend_call_method_with_0_params(op1, NULL, NULL, "count", &retval); + count = zval_get_long(&retval); + zval_ptr_dtor(&retval); + break; + } + + /* If There's no handler and it doesn't implement Countable then add a warning */ + count = 1; + } else if (Z_TYPE_P(op1) == IS_NULL) { + count = 0; + } else { + count = 1; + } + zend_error(E_WARNING, "count(): Parameter must be an array or an object that implements Countable"); + } while (0); + + ZVAL_LONG(EX_VAR(opline->result.var), count); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_CLASS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + + if (IS_CV == IS_UNUSED) { + if (UNEXPECTED(!EX(func)->common.scope)) { + SAVE_OPLINE(); + zend_error(E_WARNING, "get_class() called without object from outside a class"); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); + ZEND_VM_NEXT_OPCODE(); + } + } else { + + zval *op1; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + if (Z_TYPE_P(op1) == IS_OBJECT) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); + } else { + zend_error(E_WARNING, "get_class() expects parameter 1 to be object, %s given", zend_get_type_by_const(Z_TYPE_P(op1))); + ZVAL_FALSE(EX_VAR(opline->result.var)); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *op1; + zend_string *type; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + type = zend_zval_get_type(op1); + if (EXPECTED(type)) { + ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); + } else { + ZVAL_STRING(EX_VAR(opline->result.var), "unknown type"); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { result = EX_VAR(opline->result.var); @@ -44831,23 +49809,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_TMPVAR_HANDLER(ZEN if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } add_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { result = EX_VAR(opline->result.var); @@ -44874,23 +49852,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CV_TMPVAR_HANDLER(ZEN if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } sub_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { zend_long overflow; @@ -44920,38 +49898,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CV_TMPVAR_HANDLER(ZEN if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } mul_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); fast_div_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { result = EX_VAR(opline->result.var); @@ -44974,23 +49952,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CV_TMPVAR_HANDLER(ZEN if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } mod_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { @@ -45002,23 +49980,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_TMPVAR_HANDLER(ZEND if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } shift_left_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { @@ -45030,77 +50008,75 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_CV_TMPVAR_HANDLER(ZEND if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } shift_right_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); pow_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; - do { - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - - break; - } + if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (IS_CV != IS_CONST && IS_CV != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; + } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - } while (0); - zval_ptr_dtor_nogc(free_op2); + } else if (IS_CV != IS_CONST && IS_CV != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + + } ZEND_VM_NEXT_OPCODE(); } else { SAVE_OPLINE(); @@ -45108,24 +50084,60 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER( if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } concat_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + + zval *op1, *op2; + int result; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + result = fast_is_identical_function(op1, op2); + + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *op1, *op2; + int result; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + result = fast_is_not_identical_function(op1, op2); + + + ZEND_VM_SMART_BRANCH(result, 1); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); do { int result; @@ -45147,19 +50159,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLE } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + - zval_ptr_dtor_nogc(free_op2); } else { break; } @@ -45175,25 +50177,25 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLE if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } result = EX_VAR(opline->result.var); compare_function(result, op1, op2); ZVAL_BOOL(result, Z_LVAL_P(result) == 0); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); do { int result; @@ -45215,19 +50217,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HA } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 0; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 1; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0); - } + result = !zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + - zval_ptr_dtor_nogc(free_op2); } else { break; } @@ -45243,25 +50235,25 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HA if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } result = EX_VAR(opline->result.var); compare_function(result, op1, op2); ZVAL_BOOL(result, Z_LVAL_P(result) != 0); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); do { int result; @@ -45293,25 +50285,25 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_TMPVAR_HAND if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } result = EX_VAR(opline->result.var); compare_function(result, op1, op2); ZVAL_BOOL(result, Z_LVAL_P(result) < 0); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); do { int result; @@ -45343,40 +50335,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TM if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } result = EX_VAR(opline->result.var); compare_function(result, op1, op2); ZVAL_BOOL(result, Z_LVAL_P(result) <= 0); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); compare_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); @@ -45387,23 +50379,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_TMPVAR_HANDLER(Z if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } bitwise_or_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); @@ -45414,23 +50406,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_TMPVAR_HANDLER( if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } bitwise_and_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); @@ -45441,34 +50433,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_TMPVAR_HANDLER( if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } bitwise_xor_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); boolean_xor_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - zend_free_op free_op2, free_op_data1; + zend_free_op free_op_data1; zval *object; zval *property; zval *value; @@ -45481,10 +50473,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); do { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -45501,14 +50493,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); binary_op(zptr, zptr, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -45516,21 +50507,21 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP } } } else { - zend_assign_op_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_assign_op_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); FREE_OP(free_op_data1); - zval_ptr_dtor_nogc(free_op2); + /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - zend_free_op free_op2, free_op_data1; + zend_free_op free_op_data1; zval *var_ptr; zval *value, *container, *dim; @@ -45541,16 +50532,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP assign_dim_op_array: SEPARATE_ARRAY(container); assign_dim_op_new_array: - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV == IS_UNUSED) { var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); goto assign_dim_op_ret_null; } } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_CV == IS_CONST) { var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); } else { var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); @@ -45559,10 +50549,9 @@ assign_dim_op_new_array: goto assign_dim_op_ret_null; } ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); binary_op(var_ptr, var_ptr, value); @@ -45578,19 +50567,18 @@ assign_dim_op_new_array: } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_RW); assign_dim_op_convert_to_array: - ZVAL_NEW_ARR(container); - zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(container, zend_new_array(8)); goto assign_dim_op_new_array; } - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC); } else { if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_CV == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); } else { zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC); @@ -45608,25 +50596,24 @@ assign_dim_op_ret_null: ZVAL_NULL(EX_VAR(opline->result.var)); } } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); } } - zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper_SPEC_CV_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper_SPEC_CV_CV(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - zend_free_op free_op2; + zval *var_ptr; zval *value; SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { @@ -45635,7 +50622,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper } } else { ZVAL_DEREF(var_ptr); - SEPARATE_ZVAL_NOREF(var_ptr); binary_op(var_ptr, var_ptr, value); @@ -45644,255 +50630,254 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper } } - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_CV_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_CV_CV(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { -#if 1 && (IS_TMP_VAR|IS_VAR) == IS_UNUSED - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#if 1 && IS_CV == IS_UNUSED + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #else # if 0 || IS_CV != IS_UNUSED USE_OPLINE if (EXPECTED(1)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } # endif - ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #endif } -static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_CV_CV_DIM(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { -#if 1 && (IS_TMP_VAR|IS_VAR) == IS_UNUSED - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#if 1 && IS_CV == IS_UNUSED + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #else # if 0 || IS_CV != IS_UNUSED USE_OPLINE if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } if (EXPECTED(1)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } # endif - ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #endif } -static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) +static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC) { -#if 1 && (IS_TMP_VAR|IS_VAR) == IS_UNUSED - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +#if 1 && IS_CV == IS_UNUSED + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #else # if 0 || IS_CV != IS_UNUSED USE_OPLINE if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } if (EXPECTED(0)) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } # endif - ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_CV_TMPVAR(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); #endif } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_CV_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_DIM(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_DIM(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_CV_CV_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_TMPVAR_OBJ(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_CV_CV_OBJ(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - zend_free_op free_op2; + zval *object; zval *property; zval *zptr; @@ -45904,7 +50889,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -45922,7 +50907,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -45936,7 +50921,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } else { ZVAL_DEREF(zptr); - SEPARATE_ZVAL_NOREF(zptr); if (inc) { increment_function(zptr); @@ -45949,29 +50933,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } } } else { - zend_pre_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zend_pre_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); } } while (0); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_CV_CV(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_CV_CV(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMPVAR(int inc ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(int inc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE - zend_free_op free_op2; + zval *object; zval *property; zval *zptr; @@ -45983,7 +50966,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -46000,7 +50983,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -46013,8 +50996,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } else { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); - zval_opt_copy_ctor(zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); if (inc) { increment_function(zptr); } else { @@ -46023,38 +51005,37 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } } } else { - zend_post_incdec_overloaded_property(object, property, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); + zend_post_incdec_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var)); } } while (0); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_CV_TMPVAR(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_CV_CV(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_CV_TMPVAR(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_CV_CV(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *container, *dim, *value, *result; SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (IS_CV != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R EXECUTE_DATA_CC); + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); ZVAL_COPY_UNREF(result, value); } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { @@ -46071,24 +51052,24 @@ fetch_dim_r_slow: } } else { result = EX_VAR(opline->result.var); - zend_fetch_dimension_address_read_R(result, container, dim, (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); + zend_fetch_dimension_address_read_R(result, container, dim, IS_CV EXECUTE_DATA_CC); } - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2; + zend_free_op free_op1; zval *container; SAVE_OPLINE(); container = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -46096,17 +51077,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HAN ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2; + zend_free_op free_op1; zval *container; SAVE_OPLINE(); container = _get_zval_ptr_cv_undef_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); + zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -46114,70 +51095,58 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HA ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *container; SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zend_free_op free_op1, free_op2; - - SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - zval_ptr_dtor_nogc(free_op2); - + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_CV == IS_UNUSED) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use [] for reading"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); - + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2; + zend_free_op free_op1; zval *container; SAVE_OPLINE(); container = _get_zval_ptr_cv_undef_BP_VAR_UNSET(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); + zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -46185,33 +51154,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; - zend_free_op free_op2; + zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); - container = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + offset = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_r_no_object; + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - } else { goto fetch_obj_r_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -46219,23 +51196,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN zend_object *zobj = Z_OBJ_P(container); zval *retval; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if (IS_CV == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); + break; + } } } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(offset) == IS_UNDEF)) { + GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (UNEXPECTED(zobj->handlers->read_property == NULL)) { @@ -46246,7 +51247,7 @@ fetch_obj_r_no_object: zend_string_release(property_name); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); @@ -46254,15 +51255,14 @@ fetch_obj_r_no_object: } } while (0); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2; + zend_free_op free_op1; zval *property; zval *container; @@ -46273,9 +51273,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HAN ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - zval_ptr_dtor_nogc(free_op2); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -46283,10 +51283,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HAN ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2; + zend_free_op free_op1; zval *property; zval *container; @@ -46296,9 +51296,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HA if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); - zval_ptr_dtor_nogc(free_op2); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -46306,13 +51306,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HA ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; - zend_free_op free_op2; + zval *offset; + void **cache_slot = NULL; SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); @@ -46321,18 +51322,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HA ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); if (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_is_no_object; + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } } - } else { goto fetch_obj_is_no_object; - } + } while (0); } /* here we are sure we are dealing with an object */ @@ -46340,21 +51342,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HA zend_object *zobj = Z_OBJ_P(container); zval *retval; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + if (IS_CV == IS_CONST) { + cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset)); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(offset)) || + (EXPECTED(p->h == ZSTR_H(Z_STR_P(offset))) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, Z_STR_P(offset)))))) { + ZVAL_COPY(EX_VAR(opline->result.var), &p->val); + break; + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_ex(zobj->properties, Z_STR_P(offset), 1); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } } } } @@ -46364,7 +51388,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -46372,51 +51396,35 @@ fetch_obj_is_no_object: } } while (0); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { /* Behave like FETCH_OBJ_W */ - zend_free_op free_op1, free_op2; - zval *property; - - SAVE_OPLINE(); - container = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use temporary expression in write context"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); - zval_ptr_dtor_nogc(free_op2); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1, free_op2; + zend_free_op free_op1; zval *container, *property; SAVE_OPLINE(); @@ -46426,10 +51434,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); - zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -46437,23 +51445,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *container; SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_LIST(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); + zend_fetch_dimension_address_LIST_r(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC) EXECUTE_DATA_CC); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + + zval *retval, *container, *dim; + + SAVE_OPLINE(); + retval = EX_VAR(opline->result.var); + container = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + + if (IS_CV == IS_VAR + && Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT + && UNEXPECTED(!Z_ISREF_P(container)) + ) { + zend_error(E_NOTICE, "Attempting to set reference to non referenceable value"); + zend_fetch_dimension_address_LIST_r(retval, container, dim EXECUTE_DATA_CC); + } else { + zend_fetch_dimension_address_LIST_w(retval, container, dim EXECUTE_DATA_CC); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -46463,8 +51495,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = EX_CONSTANT((opline+1)->op1); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { do { @@ -46478,7 +51510,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -46508,13 +51540,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } while (0); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CV == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -46528,11 +51560,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -46551,24 +51583,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CONST == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -46595,23 +51623,23 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } exit_assign_obj: - zval_ptr_dtor_nogc(free_op2); + /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2, free_op_data; + zend_free_op free_op_data; zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -46621,7 +51649,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -46636,7 +51664,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -46666,13 +51694,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } while (0); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CV == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -46686,11 +51714,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -46709,24 +51737,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_TMP_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -46753,23 +51777,23 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); exit_assign_obj: - zval_ptr_dtor_nogc(free_op2); + /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2, free_op_data; + zend_free_op free_op_data; zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -46779,7 +51803,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); value = _get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -46794,7 +51818,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -46824,13 +51848,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } while (0); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CV == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -46844,11 +51868,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -46867,24 +51891,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_VAR == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -46911,23 +51931,23 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } zval_ptr_dtor_nogc(free_op_data); exit_assign_obj: - zval_ptr_dtor_nogc(free_op2); + /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *object, *property, *value, tmp; SAVE_OPLINE(); @@ -46937,7 +51957,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -46952,7 +51972,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zend_object *obj; - zval_ptr_dtor(object); + zval_ptr_dtor_nogc(object); object_init(object); Z_ADDREF_P(object); obj = Z_OBJ_P(object); @@ -46982,13 +52002,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } while (0); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CV == IS_CONST && EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*)); zend_object *zobj = Z_OBJ_P(object); zval *property_val; - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { fast_assign_obj: @@ -47002,11 +52022,11 @@ fast_assign_obj: if (EXPECTED(zobj->properties != NULL)) { if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_REFCOUNT(zobj->properties)--; + GC_DELREF(zobj->properties); } zobj->properties = zend_array_dup(zobj->properties); } - property_val = zend_hash_find(zobj->properties, Z_STR_P(property)); + property_val = zend_hash_find_ex(zobj->properties, Z_STR_P(property), 1); if (property_val) { goto fast_assign_obj; } @@ -47025,24 +52045,20 @@ fast_assign_obj: if (Z_ISREF_P(value)) { if (IS_CV == IS_VAR) { zend_reference *ref = Z_REF_P(value); - if (--GC_REFCOUNT(ref) == 0) { + if (GC_DELREF(ref) == 0) { ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); efree_size(ref, sizeof(zend_reference)); value = &tmp; } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } } else { value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } + Z_TRY_ADDREF_P(value); } - } else if (IS_CV == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); } } zend_hash_add_new(zobj->properties, Z_STR_P(property), value); @@ -47069,25 +52085,25 @@ fast_assign_obj: ZVAL_DEREF(value); } - Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); + Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } exit_assign_obj: - zval_ptr_dtor_nogc(free_op2); + /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr; - zend_free_op free_op2; + zval *value; zval *variable_ptr; zval *dim; @@ -47098,15 +52114,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_CV == IS_UNUSED) { variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); if (UNEXPECTED(variable_ptr == NULL)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); goto assign_dim_error; } } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -47115,7 +52131,7 @@ try_assign_dim_array: goto assign_dim_error; } } - value = EX_CONSTANT((opline+1)->op1); + value = RT_CONSTANT((opline+1), (opline+1)->op1); value = zend_assign_to_variable(variable_ptr, value, IS_CONST); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -47128,8 +52144,8 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = EX_CONSTANT((opline+1)->op1); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + value = RT_CONSTANT((opline+1), (opline+1)->op1); zend_assign_to_object_dim(object_ptr, dim, value); @@ -47138,27 +52154,26 @@ try_assign_dim_array: } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_CV == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - value = EX_CONSTANT((opline+1)->op1); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + value = RT_CONSTANT((opline+1), (opline+1)->op1); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); assign_dim_error: if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -47166,20 +52181,20 @@ assign_dim_error: } } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(free_op2); + if (IS_CV != IS_UNUSED) { + } /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr; - zend_free_op free_op2, free_op_data; + zend_free_op free_op_data; zval *value; zval *variable_ptr; zval *dim; @@ -47190,15 +52205,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_CV == IS_UNUSED) { variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); if (UNEXPECTED(variable_ptr == NULL)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); goto assign_dim_error; } } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -47220,7 +52235,7 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_object_dim(object_ptr, dim, value); @@ -47231,27 +52246,26 @@ try_assign_dim_array: zval_ptr_dtor_nogc(free_op_data); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_CV == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); zval_ptr_dtor_nogc(free_op_data); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); assign_dim_error: zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -47259,20 +52273,20 @@ assign_dim_error: } } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(free_op2); + if (IS_CV != IS_UNUSED) { + } /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr; - zend_free_op free_op2, free_op_data; + zend_free_op free_op_data; zval *value; zval *variable_ptr; zval *dim; @@ -47283,15 +52297,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_CV == IS_UNUSED) { variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); if (UNEXPECTED(variable_ptr == NULL)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); goto assign_dim_error; } } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -47313,7 +52327,7 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_object_dim(object_ptr, dim, value); @@ -47324,27 +52338,26 @@ try_assign_dim_array: zval_ptr_dtor_nogc(free_op_data); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_CV == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); value = _get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); zval_ptr_dtor_nogc(free_op_data); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); assign_dim_error: zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -47352,20 +52365,20 @@ assign_dim_error: } } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(free_op2); + if (IS_CV != IS_UNUSED) { + } /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr; - zend_free_op free_op2; + zval *value; zval *variable_ptr; zval *dim; @@ -47376,15 +52389,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_CV == IS_UNUSED) { variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); if (UNEXPECTED(variable_ptr == NULL)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); goto assign_dim_error; } } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -47406,7 +52419,7 @@ try_assign_dim_array: } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); zend_assign_to_object_dim(object_ptr, dim, value); @@ -47416,27 +52429,26 @@ try_assign_dim_array: } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_CV == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); UNDEF_RESULT(); HANDLE_EXCEPTION(); } else { - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); zend_assign_to_string_offset(object_ptr, dim, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL) EXECUTE_DATA_CC); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - ZVAL_NEW_ARR(object_ptr); - zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZVAL_ARR(object_ptr, zend_new_array(8)); goto try_assign_dim_array; } else { if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object_ptr))) { zend_error(E_WARNING, "Cannot use a scalar value as an array"); } - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); assign_dim_error: if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -47444,62 +52456,172 @@ assign_dim_error: } } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(free_op2); + if (IS_CV != IS_UNUSED) { + } /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { + + if (UNEXPECTED(0)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_CV); + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + /* zend_assign_to_variable() always takes care of op2, never free it! */ + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { + + if (UNEXPECTED(1)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_CV); + if (UNEXPECTED(1)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + /* zend_assign_to_variable() always takes care of op2, never free it! */ + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *variable_ptr; + zval *value_ptr; + + SAVE_OPLINE(); + value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV == IS_VAR && + UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && + UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var))) && + UNEXPECTED(!Z_ISERROR_P(EX_VAR(opline->op1.var)))) { + + zend_throw_error(NULL, "Cannot assign by reference to overloaded object"); + + + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + + } else if (IS_CV == IS_VAR && + opline->extended_value == ZEND_RETURNS_FUNCTION && + UNEXPECTED(!Z_ISREF_P(value_ptr))) { + zend_error(E_NOTICE, "Only variables should be assigned by reference"); + if (UNEXPECTED(EG(exception) != NULL)) { + + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + + value_ptr = zend_assign_to_variable(variable_ptr, value_ptr, IS_CV); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value_ptr); + } + /* zend_assign_to_variable() always takes care of op2, never free it! */ + + } else { + + if ((IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) || + (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr)))) { + variable_ptr = &EG(uninitialized_zval); + } else { + zend_assign_to_variable_reference(variable_ptr, value_ptr); + } + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); + } + + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; zend_string *op1_str, *op2_str, *str; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; - do { - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - - break; - } + if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (IS_CV != IS_CONST && IS_CV != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; + } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - } while (0); - zval_ptr_dtor_nogc(free_op2); + } else if (IS_CV != IS_CONST && IS_CV != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + + + } ZEND_VM_NEXT_OPCODE(); } @@ -47512,33 +52634,37 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - op1_str = _zval_get_string_func(op1); + op1_str = zval_get_string_func(op1); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_CV == IS_CONST) { op2_str = Z_STR_P(op2); } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { op2_str = zend_string_copy(Z_STR_P(op2)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { GET_OP2_UNDEF_CV(op2, BP_VAR_R); } - op2_str = _zval_get_string_func(op2); + op2_str = zval_get_string_func(op2); } do { if (IS_CV != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_string_addref(op2_str); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } } ZVAL_STR(EX_VAR(opline->result.var), op2_str); zend_string_release(op1_str); break; } } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CV != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { if (IS_CV == IS_CONST) { - zend_string_addref(op1_str); + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } } ZVAL_STR(EX_VAR(opline->result.var), op1_str); zend_string_release(op2_str); @@ -47552,20 +52678,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN if (IS_CV != IS_CONST) { zend_string_release(op1_str); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CV != IS_CONST) { zend_string_release(op2_str); } } while (0); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; - zend_free_op free_op2; + zval *object; zend_function *fbc; zend_class_entry *called_scope; @@ -47581,17 +52707,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && + if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { GET_OP2_UNDEF_CV(function_name, BP_VAR_R); if (UNEXPECTED(EG(exception) != NULL)) { @@ -47599,7 +52725,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA } } zend_throw_error(NULL, "Method name must be a string"); - zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); } while (0); @@ -47617,12 +52743,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { object = GET_OP1_UNDEF_CV(object, BP_VAR_R); if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); } } zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); } @@ -47632,7 +52758,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA obj = Z_OBJ_P(object); called_scope = obj->ce; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CV == IS_CONST && EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); } else { @@ -47640,22 +52766,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA if (UNEXPECTED(obj->handlers->get_method == NULL)) { zend_throw_error(NULL, "Object does not support method calls"); - zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); } /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); } - zval_ptr_dtor_nogc(free_op2); + HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CV == IS_CONST && EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { @@ -47672,10 +52798,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(obj)++; /* For $this pointer */ + GC_ADDREF(obj); /* For $this pointer */ } - zval_ptr_dtor_nogc(free_op2); if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -47689,14 +52814,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *op1, *op2, *result; op1 = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); do { int result; @@ -47718,18 +52843,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZE } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } - zval_ptr_dtor_nogc(free_op2); + result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + } else { break; } @@ -47745,17 +52860,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZE if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } result = EX_VAR(opline->result.var); compare_function(result, op1, op2); ZVAL_BOOL(result, Z_LVAL_P(result) == 0); - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -47773,20 +52888,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPV if (IS_CV == IS_TMP_VAR) { /* pass */ } else if (IS_CV == IS_CONST) { - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else if (IS_CV == IS_CV) { ZVAL_DEREF(expr_ptr); - if (Z_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + Z_TRY_ADDREF_P(expr_ptr); } else /* if (IS_CV == IS_VAR) */ { if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { zend_refcounted *ref = Z_COUNTED_P(expr_ptr); expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; efree_size(ref, sizeof(zend_reference)); @@ -47797,16 +52908,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPV } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zend_free_op free_op2; - zval *offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + if (IS_CV != IS_UNUSED) { + + zval *offset = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); zend_string *str; zend_ulong hval; add_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CV != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index; } @@ -47817,7 +52928,7 @@ str_index: hval = Z_LVAL_P(offset); num_index: zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { offset = Z_REFVAL_P(offset); goto add_again; } else if (Z_TYPE_P(offset) == IS_NULL) { @@ -47832,25 +52943,25 @@ num_index: } else if (Z_TYPE_P(offset) == IS_TRUE) { hval = 1; goto num_index; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); str = ZSTR_EMPTY_ALLOC(); goto str_index; } else { zend_error(E_WARNING, "Illegal offset type"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } - zval_ptr_dtor_nogc(free_op2); + } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - zval_ptr_dtor(expr_ptr); + zval_ptr_dtor_nogc(expr_ptr); } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *array; uint32_t size; @@ -47859,26 +52970,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HAND array = EX_VAR(opline->result.var); if (IS_CV != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - } else { - size = 0; - } - ZVAL_NEW_ARR(array); - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); - - if (IS_CV != IS_UNUSED) { + ZVAL_ARR(array, zend_new_array(size)); /* Explicitly initialize array as not-packed if flag is set */ if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init(Z_ARRVAL_P(array), 0); } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_EMPTY_ARRAY(array); + ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *container; zval *offset; zend_ulong hval; @@ -47886,7 +52993,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDL SAVE_OPLINE(); container = _get_zval_ptr_cv_undef_BP_VAR_UNSET(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + offset = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); do { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -47898,7 +53005,7 @@ unset_dim_array: offset_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { key = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CV != IS_CONST) { if (ZEND_HANDLE_NUMERIC(key, hval)) { goto num_index_dim; } @@ -47913,7 +53020,7 @@ str_index_dim: hval = Z_LVAL_P(offset); num_index_dim: zend_hash_index_del(ht, hval); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { offset = Z_REFVAL_P(offset); goto offset_again; } else if (Z_TYPE_P(offset) == IS_DOUBLE) { @@ -47931,7 +53038,7 @@ num_index_dim: } else if (Z_TYPE_P(offset) == IS_RESOURCE) { hval = Z_RES_HANDLE_P(offset); goto num_index_dim; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); key = ZSTR_EMPTY_ALLOC(); goto str_index_dim; @@ -47948,7 +53055,7 @@ num_index_dim: if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { container = GET_OP1_UNDEF_CV(container, BP_VAR_R); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { @@ -47962,15 +53069,14 @@ num_index_dim: } } while (0); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *container; zval *offset; @@ -47979,7 +53085,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDL if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { @@ -47993,7 +53099,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDL } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } else { zend_string *property_name = zval_get_string(offset); zend_error(E_NOTICE, "Trying to unset property '%s' of non-object", ZSTR_VAL(property_name)); @@ -48001,15 +53107,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDL } } while (0); - zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *container; int result; zend_ulong hval; @@ -48017,7 +53122,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_ SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + offset = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; @@ -48029,18 +53134,18 @@ isset_dim_obj_array: isset_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CV != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index_prop; } } str_index_prop: - value = zend_hash_find_ind(ht, str); + value = zend_hash_find_ex_ind(ht, str, IS_CV == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: value = zend_hash_index_find(ht, hval); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { offset = Z_REFVAL_P(offset); goto isset_again; } else if (Z_TYPE_P(offset) == IS_DOUBLE) { @@ -48058,7 +53163,7 @@ num_index_prop: } else if (Z_TYPE_P(offset) == IS_RESOURCE) { hval = Z_RES_HANDLE_P(offset); goto num_index_prop; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); str = ZSTR_EMPTY_ALLOC(); goto str_index_prop; @@ -48082,7 +53187,7 @@ num_index_prop: } } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); } @@ -48114,7 +53219,7 @@ isset_str_offset: goto isset_not_found; } } else { - if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) { + if (IS_CV & (IS_CV|IS_VAR)) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -48131,17 +53236,17 @@ isset_not_found: } isset_dim_obj_exit: - zval_ptr_dtor_nogc(free_op2); + ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op2; + zval *container; int result; zval *offset; @@ -48153,7 +53258,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); + offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); if (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -48175,4292 +53280,159 @@ isset_no_object: } else { result = ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } - zval_ptr_dtor_nogc(free_op2); ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op2; - zval *container, *dim, *value; - zend_long offset; - - container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_index_array: - if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { - offset = Z_LVAL_P(dim); - } else { - offset = zval_get_long(dim); - } - ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - SAVE_OPLINE(); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_index_array; - } else { - goto fetch_dim_r_index_slow; - } - } else { -fetch_dim_r_index_slow: - SAVE_OPLINE(); - zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim EXECUTE_DATA_CC); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - -fetch_dim_r_index_undef: - ZVAL_NULL(EX_VAR(opline->result.var)); - SAVE_OPLINE(); - zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - bitwise_not_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; - zend_free_op free_op1; - - val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(val, BP_VAR_R); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - } else { - SAVE_OPLINE(); - ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val)); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *z; - - SAVE_OPLINE(); - z = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if (Z_TYPE_P(z) == IS_STRING) { - zend_string *str = Z_STR_P(z); - - if (ZSTR_LEN(str) != 0) { - zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); - } - } else { - zend_string *str = _zval_get_string_func(z); - - if (ZSTR_LEN(str) != 0) { - zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) { - GET_OP1_UNDEF_CV(z, BP_VAR_R); - } - zend_string_release(str); - } - - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *val; - - val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZEND_VM_SET_NEXT_OPCODE(opline + 1); - ZEND_VM_CONTINUE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(val, BP_VAR_R); - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); - } else { - ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); - ZEND_VM_CONTINUE(); - } - } - - SAVE_OPLINE(); - if (i_zend_is_true(val)) { - opline++; - } else { - opline = OP_JMP_ADDR(opline, opline->op2); - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_JMP(opline); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *val; - - val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); - ZEND_VM_CONTINUE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(val, BP_VAR_R); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - if (i_zend_is_true(val)) { - opline = OP_JMP_ADDR(opline, opline->op2); - } else { - opline++; - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_JMP(opline); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *val; - - val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_INFO_P(val) == IS_TRUE)) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(val, BP_VAR_R); - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); - } else { - ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); - ZEND_VM_CONTINUE(); - } - } - - SAVE_OPLINE(); - if (i_zend_is_true(val)) { - opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); - } else { - opline = OP_JMP_ADDR(opline, opline->op2); - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_JMP(opline); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *val; - int ret; - - val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(val, BP_VAR_R); - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); - } else { - ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); - ZEND_VM_CONTINUE(); - } - } - - SAVE_OPLINE(); - ret = i_zend_is_true(val); - zval_ptr_dtor_nogc(free_op1); - if (ret) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - opline++; - } else { - ZVAL_FALSE(EX_VAR(opline->result.var)); - opline = OP_JMP_ADDR(opline, opline->op2); - } - ZEND_VM_JMP(opline); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *val; - int ret; - - val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2)); - ZEND_VM_CONTINUE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(val, BP_VAR_R); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - ret = i_zend_is_true(val); - zval_ptr_dtor_nogc(free_op1); - if (ret) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - opline = OP_JMP_ADDR(opline, opline->op2); - } else { - ZVAL_FALSE(EX_VAR(opline->result.var)); - opline++; - } - ZEND_VM_JMP(opline); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - SAVE_OPLINE(); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zval *var; - USE_OPLINE - - SAVE_OPLINE(); - var = EX_VAR(opline->op1.var); - if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) { - zend_hash_iterator_del(Z_FE_ITER_P(var)); - } - zval_ptr_dtor_nogc(var); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value, *arg; - zend_free_op free_op1; - - value = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - ZVAL_COPY_VALUE(arg, value); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { - Z_ADDREF_P(arg); - } - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; - zend_free_op free_op1; - - val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - GET_OP1_UNDEF_CV(val, BP_VAR_R); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - } else { - SAVE_OPLINE(); - ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val)); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *obj; - zend_class_entry *ce, *scope; - zend_function *clone; - zend_object_clone_obj_t clone_call; + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); SAVE_OPLINE(); - obj = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - do { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) { - obj = Z_REFVAL_P(obj); - if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) { - break; - } - } - ZVAL_UNDEF(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { - GET_OP1_UNDEF_CV(obj, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "__clone method called on non-object"); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - } while (0); - - ce = Z_OBJCE_P(obj); - clone = ce->clone; - clone_call = Z_OBJ_HT_P(obj)->clone_obj; - if (UNEXPECTED(clone_call == NULL)) { - zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); - zval_ptr_dtor_nogc(free_op1); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - - if (clone) { - if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) { - /* Ensure that if we're calling a private function, we're allowed to do so. - */ - scope = EX(func)->op_array.scope; - if (!zend_check_private(clone, scope, clone->common.function_name)) { - zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : ""); - zval_ptr_dtor_nogc(free_op1); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) { - /* Ensure that if we're calling a protected function, we're allowed to do so. - */ - scope = EX(func)->op_array.scope; - if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) { - zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(clone->common.scope->name), scope ? ZSTR_VAL(scope->name) : ""); - zval_ptr_dtor_nogc(free_op1); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } - } - - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); - - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + zend_throw_error(NULL, "Cannot yield from finally in a force-closed generator"); -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_op_array *new_op_array; - zend_free_op free_op1; - zval *inc_filename; - SAVE_OPLINE(); - inc_filename = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - new_op_array = zend_include_or_eval(inc_filename, opline->extended_value); - zval_ptr_dtor_nogc(free_op1); - if (UNEXPECTED(EG(exception) != NULL)) { - if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) { - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); - } UNDEF_RESULT(); HANDLE_EXCEPTION(); - } else if (new_op_array == ZEND_FAKE_OP_ARRAY) { - if (RETURN_VALUE_USED(opline)) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - } - } else if (EXPECTED(new_op_array != NULL)) { - zval *return_value = NULL; - zend_execute_data *call; - - if (RETURN_VALUE_USED(opline)) { - return_value = EX_VAR(opline->result.var); - ZVAL_NULL(return_value); - } - - new_op_array->scope = EX(func)->op_array.scope; - - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, - (zend_function*)new_op_array, 0, - Z_TYPE(EX(This)) != IS_OBJECT ? Z_CE(EX(This)) : NULL, - Z_TYPE(EX(This)) == IS_OBJECT ? Z_OBJ(EX(This)) : NULL); - - if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { - call->symbol_table = EX(symbol_table); - } else { - call->symbol_table = zend_rebuild_symbol_table(); - } - - call->prev_execute_data = execute_data; - i_init_code_execute_data(call, new_op_array, return_value); - if (EXPECTED(zend_execute_ex == execute_ex)) { - ZEND_VM_ENTER(); - } else { - ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); - zend_execute_ex(call); - zend_vm_stack_free_call_frame(call); - } - - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - } else if (RETURN_VALUE_USED(opline)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - } - ZEND_VM_SET_OPCODE(opline + 1); - ZEND_VM_CONTINUE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zend_free_op free_op1; - zval *ptr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - do { - if (Z_TYPE_P(ptr) == IS_LONG) { - EG(exit_status) = Z_LVAL_P(ptr); - } else { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(ptr)) { - ptr = Z_REFVAL_P(ptr); - if (Z_TYPE_P(ptr) == IS_LONG) { - EG(exit_status) = Z_LVAL_P(ptr); - break; - } - } - zend_print_variable(ptr); - } - } while (0); - zval_ptr_dtor_nogc(free_op1); - } - zend_bailout(); - ZEND_VM_NEXT_OPCODE(); /* Never reached */ -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zend_free_op free_op1; - - value = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE(); - } else { - zend_bool strict; - - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { - value = Z_REFVAL_P(value); - if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - value = GET_OP1_UNDEF_CV(value, BP_VAR_R); - } - strict = EX_USES_STRICT_TYPES(); - do { - if (EXPECTED(!strict)) { - zend_string *str; - zval tmp; - - ZVAL_COPY(&tmp, value); - if (zend_parse_arg_str_weak(&tmp, &str)) { - ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str)); - zval_ptr_dtor(&tmp); - break; - } - zval_ptr_dtor(&tmp); - } - zend_internal_type_error(strict, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value))); - ZVAL_NULL(EX_VAR(opline->result.var)); - } while (0); - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - fast_long_add_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2))); - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - add_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - fast_long_sub_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2))); - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - sub_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - zend_long overflow; - - result = EX_VAR(opline->result.var); - ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); - Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2))); - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - mul_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - fast_div_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { - SAVE_OPLINE(); - zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) { - /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */ - ZVAL_LONG(result, 0); - } else { - ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2)); - } - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - mod_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) - && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - shift_left_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) - && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - shift_right_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - pow_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - zval_ptr_dtor_nogc(free_op1); - break; - } - } - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - zval_ptr_dtor_nogc(free_op1); - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - } - zval_ptr_dtor_nogc(free_op1); - } while (0); - - ZEND_VM_NEXT_OPCODE(); - } else { - SAVE_OPLINE(); - - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - concat_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - do { - int result; - - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } - zval_ptr_dtor_nogc(free_op1); - - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) == 0); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - do { - int result; - - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 0; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 1; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0); - } - zval_ptr_dtor_nogc(free_op1); - - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) != 0); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - do { - int result; - - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) < Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) < 0); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - do { - int result; - - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) <= Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) <= 0); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - compare_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - bitwise_or_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - bitwise_and_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - bitwise_xor_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - boolean_xor_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(int type ZEND_OPCODE_HANDLER_ARGS_DC) -{ - USE_OPLINE - zend_free_op free_op1; - zval *varname; - zval *retval; - - SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - retval = zend_fetch_static_property_address(varname, (IS_TMP_VAR|IS_VAR), opline->op2, IS_CONST, type EXECUTE_DATA_CC); - - if (UNEXPECTED(retval == NULL)) { - if (EG(exception)) { - zval_ptr_dtor_nogc(free_op1); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } else { - ZEND_ASSERT(type == BP_VAR_IS); - retval = &EG(uninitialized_zval); - } - } - - zval_ptr_dtor_nogc(free_op1); - - if (type == BP_VAR_R || type == BP_VAR_IS) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - } else { - ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } else { - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container, *dim, *value, *result; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - dim = EX_CONSTANT(opline->op2); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - ZVAL_COPY_UNREF(result, value); - } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_array; - } else { - goto fetch_dim_r_slow; - } - } else { -fetch_dim_r_slow: - result = EX_VAR(opline->result.var); - zend_fetch_dimension_address_read_R_slow(result, container, dim EXECUTE_DATA_CC); - } - } else { - result = EX_VAR(opline->result.var); - zend_fetch_dimension_address_read_R(result, container, dim, IS_CONST EXECUTE_DATA_CC); - } - - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - offset = EX_CONSTANT(opline->op2); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_is_no_object; - } - } else { - goto fetch_obj_is_no_object; - } - } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zval *retval; - - if (IS_CONST == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } - } - - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } - } - } while (0); - - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_LIST(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2) EXECUTE_DATA_CC); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - zend_string *op1_str, *op2_str, *str; - - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - zval_ptr_dtor_nogc(free_op1); - break; - } - } - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - zval_ptr_dtor_nogc(free_op1); - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - } - zval_ptr_dtor_nogc(free_op1); - } while (0); - - ZEND_VM_NEXT_OPCODE(); } - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - op1_str = Z_STR_P(op1); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - op1_str = zend_string_copy(Z_STR_P(op1)); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - op1_str = _zval_get_string_func(op1); - } - if (IS_CONST == IS_CONST) { - op2_str = Z_STR_P(op2); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - op2_str = zend_string_copy(Z_STR_P(op2)); - } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - op2_str = _zval_get_string_func(op2); - } - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CONST == IS_CONST) { - zend_string_addref(op2_str); - } - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - zend_string_release(op1_str); - break; - } - } - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_string_addref(op1_str); - } - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - zend_string_release(op2_str); - break; - } - } - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(op1_str); - } - if (IS_CONST != IS_CONST) { - zend_string_release(op2_str); - } - } while (0); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *function_name; - zend_free_op free_op1; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; - - SAVE_OPLINE(); - - object = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); - function_name = EX_CONSTANT(opline->op2); + /* Set the new yielded value */ + if (IS_CV != IS_UNUSED) { - if (IS_CONST != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } while (0); - } + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_CV & (IS_CONST|IS_TMP_VAR)) { + zval *value; - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - do { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = GET_OP1_UNDEF_CV(object, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - HANDLE_EXCEPTION(); + value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); } } - zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - } while (0); - } - - obj = Z_OBJ_P(object); - called_scope = obj->ce; - - if (IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); - } else { - zend_object *orig_obj = obj; - - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); - } - - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST && - EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { - init_func_run_time_cache(&fbc->op_array); - } - } - - call_info = ZEND_CALL_NESTED_FUNCTION; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; - } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(obj)++; /* For $this pointer */ - } - - zval_ptr_dtor_nogc(free_op1); - - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = EX_CONSTANT(opline->op2); - do { - int result; - - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2))); } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } - - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) == 0); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval tmp, *varname; - zend_class_entry *ce; - zend_free_op free_op1; - - SAVE_OPLINE(); - - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - ZVAL_UNDEF(&tmp); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else if (IS_CONST == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - zend_std_unset_static_property(ce, Z_STR_P(varname)); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - int result; - zend_free_op free_op1; - zval tmp, *varname; - zend_class_entry *ce; - - SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - ZVAL_UNDEF(&tmp); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_CONST == IS_CONST) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - if (IS_CONST == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))) == ce)) { - - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_static_prop_return; - } - } - - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); - } - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - -is_static_prop_return: - if (opline->extended_value & ZEND_ISSET) { - result = value && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = !value || !i_zend_is_true(value); - } - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - int result; - zend_ulong hval; - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - offset = EX_CONSTANT(opline->op2); - - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - zval *value; - zend_string *str; - -isset_dim_obj_array: - ht = Z_ARRVAL_P(container); -isset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_CONST != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index_prop; - } - } -str_index_prop: - value = zend_hash_find_ind(ht, str); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_prop: - value = zend_hash_index_find(ht, hval); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { - offset = Z_REFVAL_P(offset); - goto isset_again; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval(Z_DVAL_P(offset)); - goto num_index_prop; - } else if (Z_TYPE_P(offset) == IS_NULL) { - str = ZSTR_EMPTY_ALLOC(); - goto str_index_prop; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index_prop; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index_prop; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - hval = Z_RES_HANDLE_P(offset); - goto num_index_prop; - } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - GET_OP2_UNDEF_CV(offset, BP_VAR_R); - str = ZSTR_EMPTY_ALLOC(); - goto str_index_prop; - } else { - zend_error(E_WARNING, "Illegal offset type in isset or empty"); - goto isset_not_found; - } - - if (opline->extended_value & ZEND_ISSET) { - /* > IS_NULL means not IS_UNDEF and not IS_NULL */ - result = value != NULL && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = (value == NULL || !i_zend_is_true(value)); - } - goto isset_dim_obj_exit; - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto isset_dim_obj_array; - } - } - - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { - offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); - } - - if (((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) { - if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) { - result = - ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0); - } else { - zend_error(E_NOTICE, "Trying to check element of non-array"); - goto isset_not_found; - } - } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */ - zend_long lval; + zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - lval = Z_LVAL_P(offset); -isset_str_offset: - if (UNEXPECTED(lval < 0)) { /* Handle negative offset */ - lval += (zend_long)Z_STRLEN_P(container); - } - if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) { - if (opline->extended_value & ZEND_ISSET) { - result = 1; + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + if (IS_CV == IS_VAR && + (value_ptr == &EG(uninitialized_zval) || + (opline->extended_value == ZEND_RETURNS_FUNCTION && + !Z_ISREF_P(value_ptr)))) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); } else { - result = (Z_STRVAL_P(container)[lval] == '0'); - } - } else { - goto isset_not_found; - } - } else { - if (IS_CONST & (IS_CV|IS_VAR)) { - ZVAL_DEREF(offset); - } - if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ - || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ - && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { - lval = zval_get_long(offset); - goto isset_str_offset; - } - goto isset_not_found; - } - } else { -isset_not_found: - result = ((opline->extended_value & ZEND_ISSET) == 0); - } - -isset_dim_obj_exit: - - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - int result; - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - offset = EX_CONSTANT(opline->op2); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; - } - } else { - goto isset_no_object; - } - } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_string *property_name = zval_get_string(offset); - zend_error(E_NOTICE, "Trying to check property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); -isset_no_object: - result = ((opline->extended_value & ZEND_ISSET) == 0); - } else { - result = - ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); - } - - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *expr; - zend_bool result; - - SAVE_OPLINE(); - expr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - -try_instanceof: - if (Z_TYPE_P(expr) == IS_OBJECT) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (EXPECTED(ce)) { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } - } else if (IS_CONST == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - zval_ptr_dtor_nogc(free_op1); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - result = ce && instanceof_function(Z_OBJCE_P(expr), ce); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { - expr = Z_REFVAL_P(expr); - goto try_instanceof; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { - GET_OP1_UNDEF_CV(expr, BP_VAR_R); - } - result = 0; - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_LONG_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op, *jump_zv; - HashTable *jumptable; - - op = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - jumptable = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); - - if (Z_TYPE_P(op) != IS_LONG) { - ZVAL_DEREF(op); - if (Z_TYPE_P(op) != IS_LONG) { - /* Wrong type, fall back to ZEND_CASE chain */ - ZEND_VM_NEXT_OPCODE(); - } - } - - jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op)); - if (jump_zv != NULL) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); - ZEND_VM_CONTINUE(); - } else { - /* default */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SWITCH_STRING_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op, *jump_zv; - HashTable *jumptable; - - op = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - jumptable = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); - - if (Z_TYPE_P(op) != IS_STRING) { - ZVAL_DEREF(op); - if (Z_TYPE_P(op) != IS_STRING) { - /* Wrong type, fall back to ZEND_CASE chain */ - ZEND_VM_NEXT_OPCODE(); - } - } - - jump_zv = zend_hash_find(jumptable, Z_STR_P(op)); - if (jump_zv != NULL) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); - ZEND_VM_CONTINUE(); - } else { - /* default */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container, *dim, *value; - zend_long offset; - - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - dim = EX_CONSTANT(opline->op2); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_index_array: - if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { - offset = Z_LVAL_P(dim); - } else { - offset = zval_get_long(dim); - } - ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - SAVE_OPLINE(); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_index_array; - } else { - goto fetch_dim_r_index_slow; - } - } else { -fetch_dim_r_index_slow: - SAVE_OPLINE(); - zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - -fetch_dim_r_index_undef: - ZVAL_NULL(EX_VAR(opline->result.var)); - SAVE_OPLINE(); - zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) -{ - USE_OPLINE - zend_free_op free_op1; - zval *varname; - zval *retval; - - SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - retval = zend_fetch_static_property_address(varname, (IS_TMP_VAR|IS_VAR), opline->op2, IS_VAR, type EXECUTE_DATA_CC); - - if (UNEXPECTED(retval == NULL)) { - if (EG(exception)) { - zval_ptr_dtor_nogc(free_op1); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } else { - ZEND_ASSERT(type == BP_VAR_IS); - retval = &EG(uninitialized_zval); - } - } - - zval_ptr_dtor_nogc(free_op1); - - if (type == BP_VAR_R || type == BP_VAR_IS) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - } else { - ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } else { - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval tmp, *varname; - zend_class_entry *ce; - zend_free_op free_op1; - - SAVE_OPLINE(); - - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - ZVAL_UNDEF(&tmp); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - zend_std_unset_static_property(ce, Z_STR_P(varname)); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - int result; - zend_free_op free_op1; - zval tmp, *varname; - zend_class_entry *ce; - - SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - ZVAL_UNDEF(&tmp); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_VAR == IS_CONST) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))) == ce)) { - - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_static_prop_return; - } - } - - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); - } - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - -is_static_prop_return: - if (opline->extended_value & ZEND_ISSET) { - result = value && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = !value || !i_zend_is_true(value); - } - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *expr; - zend_bool result; - - SAVE_OPLINE(); - expr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - -try_instanceof: - if (Z_TYPE_P(expr) == IS_OBJECT) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (EXPECTED(ce)) { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } - } else if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - zval_ptr_dtor_nogc(free_op1); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - result = ce && instanceof_function(Z_OBJCE_P(expr), ce); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { - expr = Z_REFVAL_P(expr); - goto try_instanceof; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { - GET_OP1_UNDEF_CV(expr, BP_VAR_R); - } - result = 0; - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(int type ZEND_OPCODE_HANDLER_ARGS_DC) -{ - USE_OPLINE - zend_free_op free_op1; - zval *varname; - zval *retval; - zend_string *name; - HashTable *target_symbol_table; - - SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - zend_string_addref(name); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - name = zval_get_string(varname); - } - - target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { - if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { - zval *result; - -fetch_this: - result = EX_VAR(opline->result.var); - switch (type) { - case BP_VAR_R: - if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) { - ZVAL_OBJ(result, Z_OBJ(EX(This))); - Z_ADDREF_P(result); - } else { - ZVAL_NULL(result); - zend_error(E_NOTICE,"Undefined variable: this"); - } - break; - case BP_VAR_IS: - if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) { - ZVAL_OBJ(result, Z_OBJ(EX(This))); - Z_ADDREF_P(result); - } else { - ZVAL_NULL(result); - } - break; - case BP_VAR_RW: - case BP_VAR_W: - ZVAL_UNDEF(result); - zend_throw_error(NULL, "Cannot re-assign $this"); - break; - case BP_VAR_UNSET: - ZVAL_UNDEF(result); - zend_throw_error(NULL, "Cannot unset $this"); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(name); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); - break; - case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ - } else if (Z_TYPE_P(retval) == IS_INDIRECT) { - retval = Z_INDIRECT_P(retval); - if (Z_TYPE_P(retval) == IS_UNDEF) { - if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { - goto fetch_this; - } - switch (type) { - case BP_VAR_R: - case BP_VAR_UNSET: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name)); - /* break missing intentionally */ - case BP_VAR_W: - ZVAL_NULL(retval); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - } - } - - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - zval_ptr_dtor_nogc(free_op1); - } - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(name); - } - - ZEND_ASSERT(retval != NULL); - if (type == BP_VAR_R || type == BP_VAR_IS) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - } else { - ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } else { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(int type ZEND_OPCODE_HANDLER_ARGS_DC) -{ - USE_OPLINE - zend_free_op free_op1; - zval *varname; - zval *retval; - - SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - retval = zend_fetch_static_property_address(varname, (IS_TMP_VAR|IS_VAR), opline->op2, IS_UNUSED, type EXECUTE_DATA_CC); - - if (UNEXPECTED(retval == NULL)) { - if (EG(exception)) { - zval_ptr_dtor_nogc(free_op1); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } else { - ZEND_ASSERT(type == BP_VAR_IS); - retval = &EG(uninitialized_zval); - } - } - - zval_ptr_dtor_nogc(free_op1); - - if (type == BP_VAR_R || type == BP_VAR_IS) { - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval); - } else { - ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } else { - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval tmp, *varname; - HashTable *target_symbol_table; - zend_free_op free_op1; - - SAVE_OPLINE(); - - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - ZVAL_UNDEF(&tmp); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval tmp, *varname; - zend_class_entry *ce; - zend_free_op free_op1; - - SAVE_OPLINE(); - - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - ZVAL_UNDEF(&tmp); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = GET_OP1_UNDEF_CV(varname, BP_VAR_R); - } - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - zend_std_unset_static_property(ce, Z_STR_P(varname)); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - int result; - zend_free_op free_op1; - zval tmp, *varname; - HashTable *target_symbol_table; - - SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - ZVAL_UNDEF(&tmp); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK EXECUTE_DATA_CC); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - - if (opline->extended_value & ZEND_ISSET) { - result = value && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = !value || !i_zend_is_true(value); - } - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - int result; - zend_free_op free_op1; - zval tmp, *varname; - zend_class_entry *ce; - - SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - ZVAL_UNDEF(&tmp); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { - ZVAL_STR(&tmp, zval_get_string(varname)); - varname = &tmp; - } - - if (IS_UNUSED == IS_CONST) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_static_prop_return; - } else if (UNEXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); + ZVAL_MAKE_REF(value_ptr); } - zval_ptr_dtor_nogc(free_op1); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))) == ce)) { - - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_static_prop_return; - } - } - - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); - } - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - zval_ptr_dtor_nogc(free_op1); - -is_static_prop_return: - if (opline->extended_value & ZEND_ISSET) { - result = value && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = !value || !i_zend_is_true(value); - } - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *expr; - zend_bool result; - - SAVE_OPLINE(); - expr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - -try_instanceof: - if (Z_TYPE_P(expr) == IS_OBJECT) { - zend_class_entry *ce; + ZVAL_COPY(&generator->value, value_ptr); - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (EXPECTED(ce)) { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } - } else if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ZEND_ASSERT(EG(exception)); - zval_ptr_dtor_nogc(free_op1); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); } } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - result = ce && instanceof_function(Z_OBJCE_P(expr), ce); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { - expr = Z_REFVAL_P(expr); - goto try_instanceof; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { - GET_OP1_UNDEF_CV(expr, BP_VAR_R); - } - result = 0; - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - fast_long_add_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2))); - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - add_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - fast_long_sub_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2))); - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - sub_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - zend_long overflow; - - result = EX_VAR(opline->result.var); - ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); - Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2))); - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - mul_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - fast_div_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { - SAVE_OPLINE(); - zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) { - /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */ - ZVAL_LONG(result, 0); - } else { - ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2)); - } - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - mod_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) - && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - shift_left_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) - && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - shift_right_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - pow_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - zval_ptr_dtor_nogc(free_op1); - break; - } - } - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - zval_ptr_dtor_nogc(free_op1); - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - } - zval_ptr_dtor_nogc(free_op1); - } while (0); - - ZEND_VM_NEXT_OPCODE(); - } else { - SAVE_OPLINE(); - - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - concat_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - do { - int result; + zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); + /* Consts, temporary variables and references need copying */ + if (IS_CV == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); } - zval_ptr_dtor_nogc(free_op1); - - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) == 0); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - do { - int result; + } else if (IS_CV == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2)); } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 0; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 1; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CV == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - zval_ptr_dtor_nogc(free_op1); - - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) != 0); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - do { - int result; - - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) < Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) < 0); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - do { - int result; - - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) <= Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) <= 0); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - compare_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - bitwise_or_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - bitwise_and_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - bitwise_xor_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - boolean_xor_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container, *dim, *value, *result; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - ZVAL_COPY_UNREF(result, value); - } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_array; - } else { - goto fetch_dim_r_slow; } - } else { -fetch_dim_r_slow: - result = EX_VAR(opline->result.var); - zend_fetch_dimension_address_read_R_slow(result, container, dim EXECUTE_DATA_CC); } } else { - result = EX_VAR(opline->result.var); - zend_fetch_dimension_address_read_R(result, container, dim, IS_CV EXECUTE_DATA_CC); - } - - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC), IS_CV EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_is_no_object; - } - } else { - goto fetch_obj_is_no_object; - } + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); } - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zval *retval; + /* Set the new yielded key */ + if (IS_CV != IS_UNUSED) { - if (IS_CV == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); + zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } + /* Consts, temporary variables and references need copying */ + if (IS_CV == IS_CONST) { + ZVAL_COPY_VALUE(&generator->key, key); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->key))) { + Z_ADDREF(generator->key); } - } + } else if (IS_CV == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->key, key); + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) { + ZVAL_COPY(&generator->key, Z_REFVAL_P(key)); - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); } else { - - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); + ZVAL_COPY_VALUE(&generator->key, key); + if (IS_CV == IS_CV) { + if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key); } } - } while (0); - - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_LIST(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC) EXECUTE_DATA_CC); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2; - zend_string *op1_str, *op2_str, *str; - - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - zval_ptr_dtor_nogc(free_op1); - break; - } - } - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - zval_ptr_dtor_nogc(free_op1); - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - } - zval_ptr_dtor_nogc(free_op1); - } while (0); - - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - op1_str = Z_STR_P(op1); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - op1_str = zend_string_copy(Z_STR_P(op1)); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - GET_OP1_UNDEF_CV(op1, BP_VAR_R); + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); } - op1_str = _zval_get_string_func(op1); - } - if (IS_CV == IS_CONST) { - op2_str = Z_STR_P(op2); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - op2_str = zend_string_copy(Z_STR_P(op2)); } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - op2_str = _zval_get_string_func(op2); - } - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CV == IS_CONST) { - zend_string_addref(op2_str); - } - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - zend_string_release(op1_str); - break; - } - } - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_string_addref(op1_str); - } - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - zend_string_release(op2_str); - break; - } - } - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(op1_str); - } - if (IS_CV != IS_CONST) { - zend_string_release(op2_str); - } - } while (0); - zval_ptr_dtor_nogc(free_op1); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *function_name; - zend_free_op free_op1; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; - - SAVE_OPLINE(); - - object = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - function_name = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - - if (IS_CV != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); - - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } while (0); - } - - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - do { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = GET_OP1_UNDEF_CV(object, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - } while (0); + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); } - obj = Z_OBJ_P(object); - called_scope = obj->ce; - - if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); } else { - zend_object *orig_obj = obj; - - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); - } - - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - if (IS_CV == IS_CONST && - EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { - init_func_run_time_cache(&fbc->op_array); - } - } - - call_info = ZEND_CALL_NESTED_FUNCTION; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; - } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(obj)++; /* For $this pointer */ - } - - zval_ptr_dtor_nogc(free_op1); - - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - do { - int result; - - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } - - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + generator->send_target = NULL; } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) == 0); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - int result; - zend_ulong hval; - zval *offset; + /* We increment to the next op, so we are at the correct position when the + * generator is resumed. */ + ZEND_VM_INC_OPCODE(); + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - offset = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - zval *value; - zend_string *str; -isset_dim_obj_array: - ht = Z_ARRVAL_P(container); -isset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_CV != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index_prop; - } - } -str_index_prop: - value = zend_hash_find_ind(ht, str); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_prop: - value = zend_hash_index_find(ht, hval); - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { - offset = Z_REFVAL_P(offset); - goto isset_again; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval(Z_DVAL_P(offset)); - goto num_index_prop; - } else if (Z_TYPE_P(offset) == IS_NULL) { - str = ZSTR_EMPTY_ALLOC(); - goto str_index_prop; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index_prop; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index_prop; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - hval = Z_RES_HANDLE_P(offset); - goto num_index_prop; - } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - GET_OP2_UNDEF_CV(offset, BP_VAR_R); - str = ZSTR_EMPTY_ALLOC(); - goto str_index_prop; - } else { - zend_error(E_WARNING, "Illegal offset type in isset or empty"); - goto isset_not_found; - } - - if (opline->extended_value & ZEND_ISSET) { - /* > IS_NULL means not IS_UNDEF and not IS_NULL */ - result = value != NULL && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = (value == NULL || !i_zend_is_true(value)); - } - goto isset_dim_obj_exit; - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto isset_dim_obj_array; - } - } - - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { - offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); - } - - if (((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) { - if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) { - result = - ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0); - } else { - zend_error(E_NOTICE, "Trying to check element of non-array"); - goto isset_not_found; - } - } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */ - zend_long lval; - - if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - lval = Z_LVAL_P(offset); -isset_str_offset: - if (UNEXPECTED(lval < 0)) { /* Handle negative offset */ - lval += (zend_long)Z_STRLEN_P(container); - } - if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) { - if (opline->extended_value & ZEND_ISSET) { - result = 1; - } else { - result = (Z_STRVAL_P(container)[lval] == '0'); - } - } else { - goto isset_not_found; - } - } else { - if (IS_CV & (IS_CV|IS_VAR)) { - ZVAL_DEREF(offset); - } - if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ - || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ - && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { - lval = zval_get_long(offset); - goto isset_str_offset; - } - goto isset_not_found; - } - } else { -isset_not_found: - result = ((opline->extended_value & ZEND_ISSET) == 0); - } - -isset_dim_obj_exit: - - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_free_op free_op1; - zval *container; - int result; - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; - } - } else { - goto isset_no_object; - } - } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_string *property_name = zval_get_string(offset); - zend_error(E_NOTICE, "Trying to check property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); -isset_no_object: - result = ((opline->extended_value & ZEND_ISSET) == 0); - } else { - result = - ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; zval *container, *dim, *value; zend_long offset; - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); + container = _get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC); dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_index_array: @@ -52471,1347 +53443,14 @@ fetch_dim_r_index_array: } ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { SAVE_OPLINE(); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_index_array; - } else { - goto fetch_dim_r_index_slow; - } - } else { -fetch_dim_r_index_slow: - SAVE_OPLINE(); - zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - -fetch_dim_r_index_undef: - ZVAL_NULL(EX_VAR(opline->result.var)); - SAVE_OPLINE(); - zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2, *result; - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - fast_long_add_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2))); - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - add_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - fast_long_sub_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2))); - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - sub_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - zend_long overflow; - - result = EX_VAR(opline->result.var); - ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); - Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2))); - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - mul_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - fast_div_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { - SAVE_OPLINE(); - zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) { - /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */ - ZVAL_LONG(result, 0); - } else { - ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2)); - } - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - mod_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) - && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - shift_left_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) - && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - shift_right_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - pow_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - zval_ptr_dtor_nogc(free_op1); - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - zval_ptr_dtor_nogc(free_op1); - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - } - zval_ptr_dtor_nogc(free_op1); - } while (0); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE(); - } else { - SAVE_OPLINE(); - - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - concat_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - do { - int result; - - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) == 0); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - do { - int result; - - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) != Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 0; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 1; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0); - } - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) != 0); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - do { - int result; - - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) < Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) < 0); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - do { - int result; - - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) <= Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) <= 0); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - compare_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_OR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - bitwise_or_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_AND_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - bitwise_and_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - bitwise_xor_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - boolean_xor_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *container, *dim, *value, *result; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - ZVAL_COPY_UNREF(result, value); - } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_array; - } else { - goto fetch_dim_r_slow; - } - } else { -fetch_dim_r_slow: - result = EX_VAR(opline->result.var); - zend_fetch_dimension_address_read_R_slow(result, container, dim EXECUTE_DATA_CC); - } - } else { - result = EX_VAR(opline->result.var); - zend_fetch_dimension_address_read_R(result, container, dim, (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - } - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *container; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *container; - zend_free_op free_op2; - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto fetch_obj_is_no_object; - } - } else { - goto fetch_obj_is_no_object; - } - } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zval *retval; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } else if (EXPECTED(zobj->properties != NULL)) { - retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); - if (EXPECTED(retval)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - break; - } - } - } - - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } - } - } while (0); - - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *container; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_LIST(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC) EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2; - zend_string *op1_str, *op2_str, *str; - - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - zval_ptr_dtor_nogc(free_op1); - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - zval_ptr_dtor_nogc(free_op1); - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - break; - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - } - zval_ptr_dtor_nogc(free_op1); - } while (0); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - op1_str = Z_STR_P(op1); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - op1_str = zend_string_copy(Z_STR_P(op1)); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - op1_str = _zval_get_string_func(op1); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - op2_str = Z_STR_P(op2); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - op2_str = zend_string_copy(Z_STR_P(op2)); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - op2_str = _zval_get_string_func(op2); - } - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_string_addref(op2_str); - } - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - zend_string_release(op1_str); - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_string_addref(op1_str); - } - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - zend_string_release(op2_str); - break; - } - } - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(op1_str); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(op2_str); - } - } while (0); - zval_ptr_dtor_nogc(free_op1); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *function_name; - zend_free_op free_op1, free_op2; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; - - SAVE_OPLINE(); - - object = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - GET_OP2_UNDEF_CV(function_name, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } while (0); - } - - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - do { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = GET_OP1_UNDEF_CV(object, BP_VAR_R); - if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - } while (0); - } - - obj = Z_OBJ_P(object); - called_scope = obj->ce; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(function_name)) == called_scope)) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(function_name) + sizeof(void*)); - } else { - zend_object *orig_obj = obj; - - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(obj->ce->name), Z_STRVAL_P(function_name)); - } - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(fbc->type <= ZEND_USER_FUNCTION) && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope, fbc); - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) { - init_func_run_time_cache(&fbc->op_array); - } - } - - call_info = ZEND_CALL_NESTED_FUNCTION; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - obj = NULL; - } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_RELEASE_THIS; - GC_REFCOUNT(obj)++; /* For $this pointer */ - } - - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, called_scope, obj); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *op1, *op2, *result; - - op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - do { - int result; - - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2)); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2))); - } else { - break; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - if (Z_STR_P(op1) == Z_STR_P(op2)) { - result = 1; - } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') { - if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) { - result = 0; - } else { - result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0); - } - } else { - result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0); - } - zval_ptr_dtor_nogc(free_op2); - } else { - break; - } - } else { - break; - } - ZEND_VM_SMART_BRANCH(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); - } while (0); - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - result = EX_VAR(opline->result.var); - compare_function(result, op1, op2); - ZVAL_BOOL(result, Z_LVAL_P(result) == 0); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *container; - int result; - zend_ulong hval; - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - zval *value; - zend_string *str; - -isset_dim_obj_array: - ht = Z_ARRVAL_P(container); -isset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index_prop; - } - } -str_index_prop: - value = zend_hash_find_ind(ht, str); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_prop: - value = zend_hash_index_find(ht, hval); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { - offset = Z_REFVAL_P(offset); - goto isset_again; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval(Z_DVAL_P(offset)); - goto num_index_prop; - } else if (Z_TYPE_P(offset) == IS_NULL) { - str = ZSTR_EMPTY_ALLOC(); - goto str_index_prop; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index_prop; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index_prop; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - hval = Z_RES_HANDLE_P(offset); - goto num_index_prop; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - GET_OP2_UNDEF_CV(offset, BP_VAR_R); - str = ZSTR_EMPTY_ALLOC(); - goto str_index_prop; - } else { - zend_error(E_WARNING, "Illegal offset type in isset or empty"); - goto isset_not_found; - } - - if (opline->extended_value & ZEND_ISSET) { - /* > IS_NULL means not IS_UNDEF and not IS_NULL */ - result = value != NULL && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - result = (value == NULL || !i_zend_is_true(value)); - } - goto isset_dim_obj_exit; - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto isset_dim_obj_array; - } - } - - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { - offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); - } - - if (((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_OBJECT))) { - if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) { - result = - ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISSET) == 0); - } else { - zend_error(E_NOTICE, "Trying to check element of non-array"); - goto isset_not_found; - } - } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */ - zend_long lval; - - if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - lval = Z_LVAL_P(offset); -isset_str_offset: - if (UNEXPECTED(lval < 0)) { /* Handle negative offset */ - lval += (zend_long)Z_STRLEN_P(container); - } - if (EXPECTED(lval >= 0) && (size_t)lval < Z_STRLEN_P(container)) { - if (opline->extended_value & ZEND_ISSET) { - result = 1; - } else { - result = (Z_STRVAL_P(container)[lval] == '0'); - } - } else { - goto isset_not_found; - } - } else { - if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) { - ZVAL_DEREF(offset); - } - if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ - || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ - && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { - lval = zval_get_long(offset); - goto isset_str_offset; - } - goto isset_not_found; - } - } else { -isset_not_found: - result = ((opline->extended_value & ZEND_ISSET) == 0); - } - -isset_dim_obj_exit: - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *container; - int result; - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - offset = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; - } - } else { - goto isset_no_object; - } - } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_string *property_name = zval_get_string(offset); - zend_error(E_NOTICE, "Trying to check property '%s' of non-object", ZSTR_VAL(property_name)); - zend_string_release(property_name); -isset_no_object: - result = ((opline->extended_value & ZEND_ISSET) == 0); - } else { - result = - ((opline->extended_value & ZEND_ISSET) == 0) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); - } - - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1, free_op2; - zval *container, *dim, *value; - zend_long offset; - - container = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); - dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_index_array: - if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { - offset = Z_LVAL_P(dim); - } else { - offset = zval_get_long(dim); - } - ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); - ZVAL_COPY_UNREF(EX_VAR(opline->result.var), value); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - SAVE_OPLINE(); - zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { ZEND_VM_NEXT_OPCODE(); } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { goto fetch_dim_r_index_array; @@ -53822,7 +53461,7 @@ fetch_dim_r_index_array: fetch_dim_r_index_slow: SAVE_OPLINE(); zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -53830,926 +53469,8 @@ fetch_dim_r_index_undef: ZVAL_NULL(EX_VAR(opline->result.var)); SAVE_OPLINE(); zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - Z_LVAL_P(var_ptr)++; - if (UNEXPECTED(0)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - Z_LVAL_P(var_ptr)++; - if (UNEXPECTED(1)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - fast_long_increment_function(var_ptr); - if (UNEXPECTED(0)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - fast_long_increment_function(var_ptr); - if (UNEXPECTED(1)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - fast_long_increment_function(var_ptr); - } else { - Z_DVAL_P(var_ptr)++; - } - if (UNEXPECTED(0)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - fast_long_increment_function(var_ptr); - } else { - Z_DVAL_P(var_ptr)++; - } - if (UNEXPECTED(1)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - Z_LVAL_P(var_ptr)--; - if (UNEXPECTED(0)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - Z_LVAL_P(var_ptr)--; - if (UNEXPECTED(1)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - fast_long_decrement_function(var_ptr); - if (UNEXPECTED(0)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - fast_long_decrement_function(var_ptr); - if (UNEXPECTED(1)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - fast_long_decrement_function(var_ptr); - } else { - Z_DVAL_P(var_ptr)--; - } - if (UNEXPECTED(0)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - fast_long_decrement_function(var_ptr); - } else { - Z_DVAL_P(var_ptr)--; - } - if (UNEXPECTED(1)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - Z_LVAL_P(var_ptr)++; - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_LONG_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - fast_long_increment_function(var_ptr); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - fast_long_increment_function(var_ptr); - } else { - Z_DVAL_P(var_ptr)++; - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - Z_LVAL_P(var_ptr)--; - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_LONG_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - fast_long_decrement_function(var_ptr); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - fast_long_decrement_function(var_ptr); - } else { - Z_DVAL_P(var_ptr)--; - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *value; - - value = EX_VAR(opline->op1.var); - ZVAL_DOUBLE(EX_VAR(opline->result.var), Z_DVAL_P(value)); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *value; - - value = EX_VAR(opline->op1.var); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_CONSTANT(opline->op2); - result = EX_VAR(opline->result.var); - ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_CONSTANT(opline->op2); - result = EX_VAR(opline->result.var); - fast_long_sub_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_CONSTANT(opline->op2); - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_CONSTANT(opline->op2); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_CONSTANT(opline->op2); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_CONSTANT(opline->op2); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_CONSTANT(opline->op2); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_CONSTANT(opline->op2); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_CONSTANT(opline->op2); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_CONSTANT(opline->op2); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_CONSTANT(opline->op2); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_CONSTANT(opline->op2); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_CONSTANT(opline->op2); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_CONSTANT(opline->op2); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_CONSTANT(opline->op2); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - fast_long_add_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - fast_long_sub_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_LONG(result, Z_LVAL_P(op1) * Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - zend_long overflow; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); - Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); - - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); - - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - int result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -54777,7 +53498,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) if (UNEXPECTED(execute_data == NULL)) { - static const void* labels[] = { + static const void * const labels[] = { (void*)&&ZEND_NOP_SPEC_LABEL, (void*)&&ZEND_ADD_SPEC_CONST_CONST_LABEL, (void*)&&ZEND_ADD_SPEC_CONST_TMPVAR_LABEL, @@ -54830,20 +53551,20 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_SUB_SPEC_CV_CV_LABEL, (void*)&&ZEND_MUL_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_MUL_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_MUL_SPEC_CONST_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_MUL_SPEC_CONST_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_MUL_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_MUL_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_MUL_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_MUL_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_MUL_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_MUL_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_MUL_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_MUL_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -54980,20 +53701,20 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_CONCAT_SPEC_CV_CV_LABEL, (void*)&&ZEND_BW_OR_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_BW_OR_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_BW_OR_SPEC_CONST_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_BW_OR_SPEC_CONST_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BW_OR_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_BW_OR_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_BW_OR_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_BW_OR_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BW_OR_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_BW_OR_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_BW_OR_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_BW_OR_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -55005,20 +53726,20 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BW_OR_SPEC_CV_CV_LABEL, (void*)&&ZEND_BW_AND_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_BW_AND_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_BW_AND_SPEC_CONST_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_BW_AND_SPEC_CONST_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BW_AND_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_BW_AND_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_BW_AND_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_BW_AND_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BW_AND_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_BW_AND_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_BW_AND_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_BW_AND_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -55030,20 +53751,20 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BW_AND_SPEC_CV_CV_LABEL, (void*)&&ZEND_BW_XOR_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_BW_XOR_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_BW_XOR_SPEC_CONST_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_BW_XOR_SPEC_CONST_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BW_XOR_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_BW_XOR_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_BW_XOR_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_BW_XOR_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BW_XOR_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_BW_XOR_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_BW_XOR_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_BW_XOR_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -55065,20 +53786,20 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BOOL_NOT_SPEC_CV_LABEL, (void*)&&ZEND_BOOL_XOR_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_BOOL_XOR_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_BOOL_XOR_SPEC_CONST_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_BOOL_XOR_SPEC_CONST_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -55090,20 +53811,20 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BOOL_XOR_SPEC_CV_CV_LABEL, (void*)&&ZEND_IS_IDENTICAL_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_IS_IDENTICAL_SPEC_CONST_TMP_LABEL, - (void*)&&ZEND_IS_IDENTICAL_SPEC_CONST_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_IDENTICAL_SPEC_CONST_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IS_IDENTICAL_SPEC_TMP_CONST_LABEL, (void*)&&ZEND_IS_IDENTICAL_SPEC_TMP_TMP_LABEL, - (void*)&&ZEND_IS_IDENTICAL_SPEC_TMP_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_IDENTICAL_SPEC_TMP_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IS_IDENTICAL_SPEC_VAR_CONST_LABEL, (void*)&&ZEND_IS_IDENTICAL_SPEC_VAR_TMP_LABEL, (void*)&&ZEND_IS_IDENTICAL_SPEC_VAR_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_IDENTICAL_SPEC_VAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -55115,20 +53836,20 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IS_IDENTICAL_SPEC_CV_CV_LABEL, (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_CONST_TMP_LABEL, - (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_LABEL, (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_LABEL, - (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_TMP_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_LABEL, (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_LABEL, (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -55140,20 +53861,20 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_LABEL, (void*)&&ZEND_IS_EQUAL_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_CONST_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_CONST_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -55165,20 +53886,20 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IS_EQUAL_SPEC_CV_CV_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CONST_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CONST_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -56665,16 +55386,16 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_R_SPEC_CONST_CV_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMP_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMP_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_LABEL, + (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMP_CV_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_LABEL, + (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_VAR_CV_LABEL, + (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_LABEL, (void*)&&ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_LABEL, (void*)&&ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_LABEL, @@ -57060,31 +55781,31 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_CONST_CONST_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_CONST_CV_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_CONST_CV_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVAR_CONST_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_TMPVAR_CV_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVAR_CONST_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_CV_CONST_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_CV_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_FETCH_LIST_SPEC_CV_CV_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_CV_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -58685,16 +57406,41 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_FETCH_LIST_W_SPEC_VAR_CONST_LABEL, + (void*)&&ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_FETCH_LIST_W_SPEC_VAR_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_FETCH_LIST_W_SPEC_CV_CONST_LABEL, + (void*)&&ZEND_FETCH_LIST_W_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_LIST_W_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_FETCH_LIST_W_SPEC_CV_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -58704,22 +57450,22 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ADD_LONG_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_ADD_LONG_SPEC_CONST_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ADD_LONG_SPEC_CONST_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -58729,22 +57475,22 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ADD_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_ADD_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ADD_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -58754,7 +57500,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -58835,16 +57581,16 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_MUL_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_MUL_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_MUL_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -58854,22 +57600,22 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_MUL_LONG_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_MUL_LONG_SPEC_CONST_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_MUL_LONG_SPEC_CONST_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -58879,22 +57625,22 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_MUL_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_MUL_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_MUL_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -58904,7 +57650,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -58912,21 +57658,21 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_LABEL, - (void*)&&ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, - (void*)&&ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_LABEL, - (void*)&&ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_LABEL, - (void*)&&ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, @@ -58939,9 +57685,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, @@ -58969,9 +57715,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, @@ -58987,21 +57733,21 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_LABEL, - (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, - (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_LABEL, - (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_LABEL, - (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, @@ -59014,9 +57760,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, @@ -59044,9 +57790,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, @@ -59062,21 +57808,21 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, @@ -59089,9 +57835,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, @@ -59119,9 +57865,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, @@ -59137,21 +57883,21 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, @@ -59164,9 +57910,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, @@ -59194,9 +57940,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL, @@ -59853,6 +58599,12 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_ADD_INTERFACE_SPEC_CONST): ZEND_ADD_INTERFACE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_CLASS_SPEC_TMPVAR): + ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR): + ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_DECLARE_INHERITED_CLASS_SPEC_VAR): ZEND_DECLARE_INHERITED_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -59871,12 +58623,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_INIT_DYNAMIC_CALL_SPEC_CV): ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_CLASS_SPEC_TMPVAR): - ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR): - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_BW_NOT_SPEC_CONST): ZEND_BW_NOT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -60072,8 +58818,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST): ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_LIST_SPEC_CONST_CONST): - ZEND_FETCH_LIST_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_CONST_CONST): + ZEND_FETCH_LIST_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_CONST_CONST): ZEND_FAST_CONCAT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -60129,20 +58875,137 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CONST): ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_CONST_TMP): - ZEND_IS_IDENTICAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV): + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_SPEC_CONST_TMP): - ZEND_IS_NOT_IDENTICAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_SUB_LONG_SPEC_CONST_TMPVARCV): + ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_YIELD_SPEC_CONST_TMP): - ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV): + ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV): + ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ): + ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ): + ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV): + ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ): + ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ): + ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV): + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ): + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ): + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV): + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ): + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ): + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ADD_SPEC_CONST_TMPVAR): + ZEND_ADD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SUB_SPEC_CONST_TMPVAR): + ZEND_SUB_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_DIV_SPEC_CONST_TMPVAR): + ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_MOD_SPEC_CONST_TMPVAR): + ZEND_MOD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SL_SPEC_CONST_TMPVAR): + ZEND_SL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SR_SPEC_CONST_TMPVAR): + ZEND_SR_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POW_SPEC_CONST_TMPVAR): + ZEND_POW_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CONCAT_SPEC_CONST_TMPVAR): + ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_SPEC_CONST_TMPVAR): + ZEND_IS_SMALLER_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVAR): + ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SPACESHIP_SPEC_CONST_TMPVAR): + ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR): + ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR): + ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR): + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR): + ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR): + ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR): + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR): + ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_CONST_VAR): - ZEND_IS_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR): + ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR): + ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR): + ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VAR): - ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR): + ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CASE_SPEC_CONST_TMPVAR): + ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR): + ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR): + ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR): + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR): + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVAR): + ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_YIELD_SPEC_CONST_TMP): + ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_STATIC_PROP_R_SPEC_CONST_VAR): ZEND_FETCH_STATIC_PROP_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -60258,9 +59121,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_SUB_SPEC_CONST_CV): ZEND_SUB_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_MUL_SPEC_CONST_CV): - ZEND_MUL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_DIV_SPEC_CONST_CV): ZEND_DIV_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -60279,18 +59139,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_CONCAT_SPEC_CONST_CV): ZEND_CONCAT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_CONST_CV): - ZEND_IS_IDENTICAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CV): - ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CONST_CV): - ZEND_IS_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CONST_CV): - ZEND_IS_NOT_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_IS_SMALLER_SPEC_CONST_CV): ZEND_IS_SMALLER_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -60300,18 +59148,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_SPACESHIP_SPEC_CONST_CV): ZEND_SPACESHIP_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_OR_SPEC_CONST_CV): - ZEND_BW_OR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_AND_SPEC_CONST_CV): - ZEND_BW_AND_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_XOR_SPEC_CONST_CV): - ZEND_BW_XOR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BOOL_XOR_SPEC_CONST_CV): - ZEND_BOOL_XOR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_CONST_CV): ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -60330,8 +59166,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV): ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_LIST_SPEC_CONST_CV): - ZEND_FETCH_LIST_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_CONST_CV): + ZEND_FETCH_LIST_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_CONST_CV): ZEND_FAST_CONCAT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -60369,209 +59205,662 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CV): ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_SPEC_CONST_TMPVAR): - ZEND_ADD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED): + ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_SUB_SPEC_CONST_TMPVAR): - ZEND_SUB_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED): + ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_MUL_SPEC_CONST_TMPVAR): - ZEND_MUL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED): + ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_DIV_SPEC_CONST_TMPVAR): - ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_USED): + ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_MOD_SPEC_CONST_TMPVAR): - ZEND_MOD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED): + ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_SL_SPEC_CONST_TMPVAR): - ZEND_SL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED): + ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_SR_SPEC_CONST_TMPVAR): - ZEND_SR_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED): + ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_POW_SPEC_CONST_TMPVAR): - ZEND_POW_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED): + ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_CONCAT_SPEC_CONST_TMPVAR): - ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED): + ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CONST_TMPVAR): - ZEND_IS_EQUAL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_USED): + ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CONST_TMPVAR): - ZEND_IS_NOT_EQUAL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED): + ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_SPEC_CONST_TMPVAR): - ZEND_IS_SMALLER_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED): + ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVAR): - ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV): + ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_SPACESHIP_SPEC_CONST_TMPVAR): - ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_POST_INC_LONG_SPEC_TMPVARCV): + ZEND_POST_INC_LONG_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_OR_SPEC_CONST_TMPVAR): - ZEND_BW_OR_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_POST_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV): + ZEND_POST_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_AND_SPEC_CONST_TMPVAR): - ZEND_BW_AND_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV): + ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_XOR_SPEC_CONST_TMPVAR): - ZEND_BW_XOR_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_POST_DEC_LONG_SPEC_TMPVARCV): + ZEND_POST_DEC_LONG_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_BOOL_XOR_SPEC_CONST_TMPVAR): - ZEND_BOOL_XOR_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_POST_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV): + ZEND_POST_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR): - ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV): + ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR): - ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV): + ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR): - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST): + ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR): - ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_ADD_LONG_SPEC_TMPVARCV_CONST): + ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR): - ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST): + ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR): - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST): + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_LIST_SPEC_CONST_TMPVAR): - ZEND_FETCH_LIST_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_SUB_LONG_SPEC_TMPVARCV_CONST): + ZEND_SUB_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR): - ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST): + ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR): - ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST): + ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR): - ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_MUL_LONG_SPEC_TMPVARCV_CONST): + ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR): - ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST): + ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_CASE_SPEC_CONST_TMPVAR): - ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST): + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR): - ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ): + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR): - ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ): + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR): - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST): + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR): - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ): + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVAR): - ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ): + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV): - ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST): + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_LONG_SPEC_CONST_TMPVARCV): - ZEND_ADD_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ): + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_DOUBLE_SPEC_CONST_TMPVARCV): - ZEND_ADD_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ): + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV): - ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST): + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_SUB_LONG_SPEC_CONST_TMPVARCV): - ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ): + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV): - ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ): + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_MUL_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV): - ZEND_MUL_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST): + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_MUL_LONG_SPEC_CONST_TMPVARCV): - ZEND_MUL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ): + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_MUL_DOUBLE_SPEC_CONST_TMPVARCV): - ZEND_MUL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ): + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV): - ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST): + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ): - ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ): + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ): - ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ): + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV): - ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST): + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ): - ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ): + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ): - ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ): + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV): - ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST): + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ): - ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ): + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ): - ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ): + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV): - ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV): + ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ): - ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV): + ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ): - ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV): + ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV): - ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV): + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ): - ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV): + ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ): - ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV): + ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV): - ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV): + ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ): - ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV): + ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ): - ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV): + ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV): - ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV): + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ): - ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ): + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ): - ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ): + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV): - ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV): + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ): - ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ): + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ): - ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ): + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV): + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ): + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ): + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV): + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ): + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ): + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV): + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ): + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ): + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV): + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ): + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ): + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV): + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ): + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ): + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV): + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ): + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ): + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BW_NOT_SPEC_TMPVAR): + ZEND_BW_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BOOL_NOT_SPEC_TMPVAR): + ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ECHO_SPEC_TMPVAR): + ZEND_ECHO_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_JMPZ_SPEC_TMPVAR): + ZEND_JMPZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_JMPNZ_SPEC_TMPVAR): + ZEND_JMPNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_JMPZNZ_SPEC_TMPVAR): + ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_JMPZ_EX_SPEC_TMPVAR): + ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_JMPNZ_EX_SPEC_TMPVAR): + ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FREE_SPEC_TMPVAR): + ZEND_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FE_FREE_SPEC_TMPVAR): + ZEND_FE_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SEND_VAL_SPEC_TMPVAR): + ZEND_SEND_VAL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BOOL_SPEC_TMPVAR): + ZEND_BOOL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CLONE_SPEC_TMPVAR): + ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR): + ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_EXIT_SPEC_TMPVAR): + ZEND_EXIT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_STRLEN_SPEC_TMPVAR): + ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ADD_SPEC_TMPVAR_CONST): + ZEND_ADD_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SUB_SPEC_TMPVAR_CONST): + ZEND_SUB_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_MUL_SPEC_TMPVAR_CONST): + ZEND_MUL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_DIV_SPEC_TMPVAR_CONST): + ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_MOD_SPEC_TMPVAR_CONST): + ZEND_MOD_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SL_SPEC_TMPVAR_CONST): + ZEND_SL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SR_SPEC_TMPVAR_CONST): + ZEND_SR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POW_SPEC_TMPVAR_CONST): + ZEND_POW_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CONCAT_SPEC_TMPVAR_CONST): + ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST): + ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST): + ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_SPEC_TMPVAR_CONST): + ZEND_IS_SMALLER_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CONST): + ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMPVAR_CONST): + ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BW_OR_SPEC_TMPVAR_CONST): + ZEND_BW_OR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BW_AND_SPEC_TMPVAR_CONST): + ZEND_BW_AND_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BW_XOR_SPEC_TMPVAR_CONST): + ZEND_BW_XOR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BOOL_XOR_SPEC_TMPVAR_CONST): + ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_CONST): + ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_CONST): + ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_CONST): + ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_CONST): + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_CONST): + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_CONST): + ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST): + ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST): + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST): + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST): + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_TMPVAR_CONST): + ZEND_FETCH_LIST_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST): + ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST): + ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CASE_SPEC_TMPVAR_CONST): + ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_CONST): + ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_CONST): + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST): + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST): + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMPVAR_CONST): + ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SWITCH_LONG_SPEC_TMPVAR_CONST): + ZEND_SWITCH_LONG_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SWITCH_STRING_SPEC_TMPVAR_CONST): + ZEND_SWITCH_STRING_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST): + ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ADD_SPEC_TMPVAR_TMPVAR): + ZEND_ADD_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SUB_SPEC_TMPVAR_TMPVAR): + ZEND_SUB_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_MUL_SPEC_TMPVAR_TMPVAR): + ZEND_MUL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_DIV_SPEC_TMPVAR_TMPVAR): + ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_MOD_SPEC_TMPVAR_TMPVAR): + ZEND_MOD_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SL_SPEC_TMPVAR_TMPVAR): + ZEND_SL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SR_SPEC_TMPVAR_TMPVAR): + ZEND_SR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POW_SPEC_TMPVAR_TMPVAR): + ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CONCAT_SPEC_TMPVAR_TMPVAR): + ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR): + ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR): + ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_SPEC_TMPVAR_TMPVAR): + ZEND_IS_SMALLER_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_TMPVAR): + ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR): + ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BW_OR_SPEC_TMPVAR_TMPVAR): + ZEND_BW_OR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BW_AND_SPEC_TMPVAR_TMPVAR): + ZEND_BW_AND_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BW_XOR_SPEC_TMPVAR_TMPVAR): + ZEND_BW_XOR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR): + ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR): + ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR): + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR): + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR): + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_TMPVAR_TMPVAR): + ZEND_FETCH_LIST_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR): + ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR): + ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CASE_SPEC_TMPVAR_TMPVAR): + ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR): + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR): + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR): + ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_VAR): + ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_VAR): + ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_VAR): + ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_VAR): + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_VAR): + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_VAR): + ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_VAR): + ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_VAR): + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMPVAR_VAR): + ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_R_SPEC_TMPVAR_UNUSED): + ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_W_SPEC_TMPVAR_UNUSED): + ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED): + ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED): + ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED): + ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED): + ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_UNUSED): + ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_UNUSED): + ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_UNUSED): + ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_UNUSED): + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_UNUSED): + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_UNUSED): + ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED): + ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_UNUSED): + ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED): + ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_UNUSED): + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED): + ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ADD_SPEC_TMPVAR_CV): + ZEND_ADD_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SUB_SPEC_TMPVAR_CV): + ZEND_SUB_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_DIV_SPEC_TMPVAR_CV): + ZEND_DIV_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_MOD_SPEC_TMPVAR_CV): + ZEND_MOD_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SL_SPEC_TMPVAR_CV): + ZEND_SL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SR_SPEC_TMPVAR_CV): + ZEND_SR_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POW_SPEC_TMPVAR_CV): + ZEND_POW_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CONCAT_SPEC_TMPVAR_CV): + ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_SPEC_TMPVAR_CV): + ZEND_IS_SMALLER_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CV): + ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMPVAR_CV): + ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV): + ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV): + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV): + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV): + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_TMPVAR_CV): + ZEND_FETCH_LIST_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMPVAR_CV): + ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV): + ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CASE_SPEC_TMPVAR_CV): + ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV): + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV): + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CV): + ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); HYBRID_CASE(ZEND_RETURN_SPEC_TMP): ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -60630,9 +59919,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST): ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_TMP_CONST): - ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST): ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -60654,6 +59940,24 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_IN_ARRAY_SPEC_TMP_CONST): ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR): + ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR): + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ROPE_ADD_SPEC_TMP_TMPVAR): + ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ROPE_END_SPEC_TMP_TMPVAR): + ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR): + ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR): + ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_TMP_TMP): ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -60663,12 +59967,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_YIELD_SPEC_TMP_TMP): ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_TMP_VAR): - ZEND_IS_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_SPEC_TMP_VAR): - ZEND_IS_NOT_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_YIELD_SPEC_TMP_VAR): ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -60696,18 +59994,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_GET_TYPE_SPEC_TMP_UNUSED): ZEND_GET_TYPE_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_TMP_CV): - ZEND_IS_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CV): - ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV): ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_TMP_CV): - ZEND_FETCH_OBJ_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV): ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -60729,27 +60018,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_BIND_LEXICAL_SPEC_TMP_CV): ZEND_BIND_LEXICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR): - ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_TMP_TMPVAR): - ZEND_FETCH_OBJ_R_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR): - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ROPE_ADD_SPEC_TMP_TMPVAR): - ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ROPE_END_SPEC_TMP_TMPVAR): - ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR): - ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR): - ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_PRE_INC_SPEC_VAR_RETVAL_UNUSED): ZEND_PRE_INC_SPEC_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -60984,9 +60252,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST): ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_VAR_CONST): - ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_VAR_CONST): ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -60999,6 +60264,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST): ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_LIST_W_SPEC_VAR_CONST): + ZEND_FETCH_LIST_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST): ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -61053,6 +60321,192 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_IN_ARRAY_SPEC_VAR_CONST): ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR): + ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_DIM): + ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_OBJ): + ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR): + ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_DIM): + ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_OBJ): + ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR): + ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_DIM): + ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_OBJ): + ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR): + ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_DIM): + ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_OBJ): + ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR): + ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_DIM): + ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_OBJ): + ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR): + ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_DIM): + ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_OBJ): + ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR): + ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_DIM): + ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_OBJ): + ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR): + ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_DIM): + ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_OBJ): + ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR): + ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_DIM): + ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_OBJ): + ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR): + ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_DIM): + ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_OBJ): + ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR): + ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_DIM): + ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_OBJ): + ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR): + ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_DIM): + ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_OBJ): + ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR): + ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_PRE_DEC_OBJ_SPEC_VAR_TMPVAR): + ZEND_PRE_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR): + ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POST_DEC_OBJ_SPEC_VAR_TMPVAR): + ZEND_POST_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR): + ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR): + ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR): + ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR): + ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR): + ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR): + ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR): + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR): + ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR): + ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST): + ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP): + ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR): + ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV): + ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST): + ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP): + ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR): + ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV): + ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR): + ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR): + ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR): + ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_UNSET_DIM_SPEC_VAR_TMPVAR): + ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR): + ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_VAR_TMP): ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -61173,12 +60627,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_GET_TYPE_SPEC_VAR_UNUSED): ZEND_GET_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_VAR_CV): - ZEND_IS_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CV): - ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_VAR_CV): ZEND_ASSIGN_ADD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -61311,9 +60759,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV): ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_VAR_CV): - ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_VAR_CV): ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -61326,6 +60771,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV): ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_LIST_W_SPEC_VAR_CV): + ZEND_FETCH_LIST_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST): ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -61383,192 +60831,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED): ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR): - ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_DIM): - ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_OBJ): - ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR): - ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_DIM): - ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_OBJ): - ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR): - ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_DIM): - ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_OBJ): - ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR): - ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_DIM): - ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_OBJ): - ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR): - ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_DIM): - ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_OBJ): - ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR): - ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_DIM): - ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_OBJ): - ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR): - ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_DIM): - ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_OBJ): - ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR): - ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_DIM): - ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_OBJ): - ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR): - ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_DIM): - ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_OBJ): - ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR): - ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_DIM): - ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_OBJ): - ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR): - ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_DIM): - ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_OBJ): - ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR): - ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_DIM): - ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_OBJ): - ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR): - ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_DEC_OBJ_SPEC_VAR_TMPVAR): - ZEND_PRE_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR): - ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POST_DEC_OBJ_SPEC_VAR_TMPVAR): - ZEND_POST_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR): - ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR): - ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR): - ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR): - ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_VAR_TMPVAR): - ZEND_FETCH_OBJ_R_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR): - ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR): - ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR): - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR): - ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST): - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP): - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR): - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV): - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST): - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP): - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR): - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV): - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR): - ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR): - ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR): - ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_UNSET_DIM_SPEC_VAR_TMPVAR): - ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR): - ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_NEW_SPEC_UNUSED): ZEND_NEW_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -61680,6 +60942,99 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_YIELD_SPEC_UNUSED_CONST): ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_UNUSED_TMPVAR_OBJ): + ZEND_ASSIGN_ADD_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SUB_SPEC_UNUSED_TMPVAR_OBJ): + ZEND_ASSIGN_SUB_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_MUL_SPEC_UNUSED_TMPVAR_OBJ): + ZEND_ASSIGN_MUL_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIV_SPEC_UNUSED_TMPVAR_OBJ): + ZEND_ASSIGN_DIV_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_MOD_SPEC_UNUSED_TMPVAR_OBJ): + ZEND_ASSIGN_MOD_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SL_SPEC_UNUSED_TMPVAR_OBJ): + ZEND_ASSIGN_SL_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SR_SPEC_UNUSED_TMPVAR_OBJ): + ZEND_ASSIGN_SR_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_CONCAT_SPEC_UNUSED_TMPVAR_OBJ): + ZEND_ASSIGN_CONCAT_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_OR_SPEC_UNUSED_TMPVAR_OBJ): + ZEND_ASSIGN_BW_OR_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_AND_SPEC_UNUSED_TMPVAR_OBJ): + ZEND_ASSIGN_BW_AND_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_TMPVAR_OBJ): + ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_POW_SPEC_UNUSED_TMPVAR_OBJ): + ZEND_ASSIGN_POW_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR): + ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_PRE_DEC_OBJ_SPEC_UNUSED_TMPVAR): + ZEND_PRE_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR): + ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POST_DEC_OBJ_SPEC_UNUSED_TMPVAR): + ZEND_POST_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR): + ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR): + ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR): + ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR): + ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR): + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR): + ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST): + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP): + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR): + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV): + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR): + ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR): + ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR): + ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR): + ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR): + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_YIELD_SPEC_UNUSED_TMP): ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -61809,99 +61164,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_YIELD_SPEC_UNUSED_CV): ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_UNUSED_TMPVAR_OBJ): - ZEND_ASSIGN_ADD_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SUB_SPEC_UNUSED_TMPVAR_OBJ): - ZEND_ASSIGN_SUB_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_MUL_SPEC_UNUSED_TMPVAR_OBJ): - ZEND_ASSIGN_MUL_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIV_SPEC_UNUSED_TMPVAR_OBJ): - ZEND_ASSIGN_DIV_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_MOD_SPEC_UNUSED_TMPVAR_OBJ): - ZEND_ASSIGN_MOD_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SL_SPEC_UNUSED_TMPVAR_OBJ): - ZEND_ASSIGN_SL_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SR_SPEC_UNUSED_TMPVAR_OBJ): - ZEND_ASSIGN_SR_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_CONCAT_SPEC_UNUSED_TMPVAR_OBJ): - ZEND_ASSIGN_CONCAT_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_OR_SPEC_UNUSED_TMPVAR_OBJ): - ZEND_ASSIGN_BW_OR_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_AND_SPEC_UNUSED_TMPVAR_OBJ): - ZEND_ASSIGN_BW_AND_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_TMPVAR_OBJ): - ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_POW_SPEC_UNUSED_TMPVAR_OBJ): - ZEND_ASSIGN_POW_SPEC_UNUSED_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR): - ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_DEC_OBJ_SPEC_UNUSED_TMPVAR): - ZEND_PRE_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR): - ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POST_DEC_OBJ_SPEC_UNUSED_TMPVAR): - ZEND_POST_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR): - ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR): - ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR): - ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR): - ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR): - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR): - ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST): - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP): - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR): - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV): - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR): - ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR): - ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR): - ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR): - ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR): - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_BW_NOT_SPEC_CV): ZEND_BW_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -62253,8 +61515,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST): ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_LIST_SPEC_CV_CONST): - ZEND_FETCH_LIST_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_CV_CONST): + ZEND_FETCH_LIST_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_LIST_W_SPEC_CV_CONST): + ZEND_FETCH_LIST_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST): ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -62343,6 +61608,276 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST): ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_ADD_SPEC_CV_TMPVAR): + ZEND_ADD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SUB_SPEC_CV_TMPVAR): + ZEND_SUB_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_MUL_SPEC_CV_TMPVAR): + ZEND_MUL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_DIV_SPEC_CV_TMPVAR): + ZEND_DIV_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_MOD_SPEC_CV_TMPVAR): + ZEND_MOD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SL_SPEC_CV_TMPVAR): + ZEND_SL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SR_SPEC_CV_TMPVAR): + ZEND_SR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POW_SPEC_CV_TMPVAR): + ZEND_POW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CONCAT_SPEC_CV_TMPVAR): + ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CV_TMPVAR): + ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR): + ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_SPEC_CV_TMPVAR): + ZEND_IS_SMALLER_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMPVAR): + ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SPACESHIP_SPEC_CV_TMPVAR): + ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BW_OR_SPEC_CV_TMPVAR): + ZEND_BW_OR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BW_AND_SPEC_CV_TMPVAR): + ZEND_BW_AND_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BW_XOR_SPEC_CV_TMPVAR): + ZEND_BW_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BOOL_XOR_SPEC_CV_TMPVAR): + ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR): + ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_DIM): + ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_OBJ): + ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR): + ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_DIM): + ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_OBJ): + ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR): + ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_DIM): + ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_OBJ): + ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR): + ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_DIM): + ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_OBJ): + ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR): + ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_DIM): + ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_OBJ): + ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SL_SPEC_CV_TMPVAR): + ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_DIM): + ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_OBJ): + ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SR_SPEC_CV_TMPVAR): + ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_DIM): + ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_OBJ): + ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR): + ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_DIM): + ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_OBJ): + ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR): + ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_DIM): + ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_OBJ): + ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR): + ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_DIM): + ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_OBJ): + ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR): + ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_DIM): + ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_OBJ): + ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_POW_SPEC_CV_TMPVAR): + ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_DIM): + ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_OBJ): + ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR): + ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_PRE_DEC_OBJ_SPEC_CV_TMPVAR): + ZEND_PRE_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR): + ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POST_DEC_OBJ_SPEC_CV_TMPVAR): + ZEND_POST_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR): + ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR): + ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR): + ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR): + ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR): + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR): + ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR): + ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR): + ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR): + ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR): + ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR): + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR): + ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_CV_TMPVAR): + ZEND_FETCH_LIST_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_LIST_W_SPEC_CV_TMPVAR): + ZEND_FETCH_LIST_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST): + ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP): + ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR): + ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV): + ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST): + ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP): + ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR): + ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV): + ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_CV_TMPVAR): + ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR): + ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CASE_SPEC_CV_TMPVAR): + ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR): + ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_CV_TMPVAR): + ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_UNSET_DIM_SPEC_CV_TMPVAR): + ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_CV_TMPVAR): + ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR): + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR): + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVAR): + ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_CV_TMP): ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -62760,8 +62295,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV): ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_LIST_SPEC_CV_CV): - ZEND_FETCH_LIST_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_CV_CV): + ZEND_FETCH_LIST_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_LIST_W_SPEC_CV_CV): + ZEND_FETCH_LIST_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST): ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -62829,888 +62367,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CV): ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_SPEC_CV_TMPVAR): - ZEND_ADD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SUB_SPEC_CV_TMPVAR): - ZEND_SUB_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_MUL_SPEC_CV_TMPVAR): - ZEND_MUL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_DIV_SPEC_CV_TMPVAR): - ZEND_DIV_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_MOD_SPEC_CV_TMPVAR): - ZEND_MOD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SL_SPEC_CV_TMPVAR): - ZEND_SL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SR_SPEC_CV_TMPVAR): - ZEND_SR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POW_SPEC_CV_TMPVAR): - ZEND_POW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CONCAT_SPEC_CV_TMPVAR): - ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CV_TMPVAR): - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR): - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_SPEC_CV_TMPVAR): - ZEND_IS_SMALLER_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMPVAR): - ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SPACESHIP_SPEC_CV_TMPVAR): - ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_OR_SPEC_CV_TMPVAR): - ZEND_BW_OR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_AND_SPEC_CV_TMPVAR): - ZEND_BW_AND_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_XOR_SPEC_CV_TMPVAR): - ZEND_BW_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BOOL_XOR_SPEC_CV_TMPVAR): - ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR): - ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_DIM): - ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_OBJ): - ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR): - ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_DIM): - ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_OBJ): - ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR): - ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_DIM): - ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_OBJ): - ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR): - ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_DIM): - ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_OBJ): - ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR): - ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_DIM): - ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_OBJ): - ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SL_SPEC_CV_TMPVAR): - ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_DIM): - ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_OBJ): - ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SR_SPEC_CV_TMPVAR): - ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_DIM): - ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_OBJ): - ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR): - ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_DIM): - ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_OBJ): - ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR): - ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_DIM): - ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_OBJ): - ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR): - ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_DIM): - ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_OBJ): - ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR): - ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_DIM): - ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_OBJ): - ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_POW_SPEC_CV_TMPVAR): - ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_DIM): - ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_OBJ): - ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR): - ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_DEC_OBJ_SPEC_CV_TMPVAR): - ZEND_PRE_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR): - ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POST_DEC_OBJ_SPEC_CV_TMPVAR): - ZEND_POST_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR): - ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR): - ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR): - ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR): - ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR): - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR): - ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR): - ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR): - ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR): - ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR): - ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR): - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR): - ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_LIST_SPEC_CV_TMPVAR): - ZEND_FETCH_LIST_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST): - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP): - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR): - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV): - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST): - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP): - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR): - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV): - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_CV_TMPVAR): - ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR): - ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CASE_SPEC_CV_TMPVAR): - ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR): - ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_CV_TMPVAR): - ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_UNSET_DIM_SPEC_CV_TMPVAR): - ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_CV_TMPVAR): - ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR): - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR): - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVAR): - ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_NOT_SPEC_TMPVAR): - ZEND_BW_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BOOL_NOT_SPEC_TMPVAR): - ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ECHO_SPEC_TMPVAR): - ZEND_ECHO_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMPZ_SPEC_TMPVAR): - ZEND_JMPZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMPNZ_SPEC_TMPVAR): - ZEND_JMPNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMPZNZ_SPEC_TMPVAR): - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMPZ_EX_SPEC_TMPVAR): - ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMPNZ_EX_SPEC_TMPVAR): - ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FREE_SPEC_TMPVAR): - ZEND_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FE_FREE_SPEC_TMPVAR): - ZEND_FE_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SEND_VAL_SPEC_TMPVAR): - ZEND_SEND_VAL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BOOL_SPEC_TMPVAR): - ZEND_BOOL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CLONE_SPEC_TMPVAR): - ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR): - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_EXIT_SPEC_TMPVAR): - ZEND_EXIT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_STRLEN_SPEC_TMPVAR): - ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_SPEC_TMPVAR_CONST): - ZEND_ADD_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SUB_SPEC_TMPVAR_CONST): - ZEND_SUB_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_MUL_SPEC_TMPVAR_CONST): - ZEND_MUL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_DIV_SPEC_TMPVAR_CONST): - ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_MOD_SPEC_TMPVAR_CONST): - ZEND_MOD_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SL_SPEC_TMPVAR_CONST): - ZEND_SL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SR_SPEC_TMPVAR_CONST): - ZEND_SR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POW_SPEC_TMPVAR_CONST): - ZEND_POW_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CONCAT_SPEC_TMPVAR_CONST): - ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST): - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST): - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_SPEC_TMPVAR_CONST): - ZEND_IS_SMALLER_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CONST): - ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMPVAR_CONST): - ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_OR_SPEC_TMPVAR_CONST): - ZEND_BW_OR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_AND_SPEC_TMPVAR_CONST): - ZEND_BW_AND_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_XOR_SPEC_TMPVAR_CONST): - ZEND_BW_XOR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BOOL_XOR_SPEC_TMPVAR_CONST): - ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_CONST): - ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_CONST): - ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_CONST): - ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_CONST): - ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_CONST): - ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_CONST): - ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST): - ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST): - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST): - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_LIST_SPEC_TMPVAR_CONST): - ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST): - ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST): - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CASE_SPEC_TMPVAR_CONST): - ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_CONST): - ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_CONST): - ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST): - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST): - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMPVAR_CONST): - ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SWITCH_LONG_SPEC_TMPVAR_CONST): - ZEND_SWITCH_LONG_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SWITCH_STRING_SPEC_TMPVAR_CONST): - ZEND_SWITCH_STRING_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST): - ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_VAR): - ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_VAR): - ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_VAR): - ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_VAR): - ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_VAR): - ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_VAR): - ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_VAR): - ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_VAR): - ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMPVAR_VAR): - ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_R_SPEC_TMPVAR_UNUSED): - ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_W_SPEC_TMPVAR_UNUSED): - ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED): - ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED): - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED): - ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED): - ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_UNUSED): - ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_UNUSED): - ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_UNUSED): - ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_UNUSED): - ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_UNUSED): - ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_UNUSED): - ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED): - ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_UNUSED): - ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED): - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_UNUSED): - ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED): - ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_SPEC_TMPVAR_CV): - ZEND_ADD_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SUB_SPEC_TMPVAR_CV): - ZEND_SUB_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_MUL_SPEC_TMPVAR_CV): - ZEND_MUL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_DIV_SPEC_TMPVAR_CV): - ZEND_DIV_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_MOD_SPEC_TMPVAR_CV): - ZEND_MOD_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SL_SPEC_TMPVAR_CV): - ZEND_SL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SR_SPEC_TMPVAR_CV): - ZEND_SR_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POW_SPEC_TMPVAR_CV): - ZEND_POW_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CONCAT_SPEC_TMPVAR_CV): - ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_CV): - ZEND_IS_EQUAL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CV): - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_SPEC_TMPVAR_CV): - ZEND_IS_SMALLER_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CV): - ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMPVAR_CV): - ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_OR_SPEC_TMPVAR_CV): - ZEND_BW_OR_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_AND_SPEC_TMPVAR_CV): - ZEND_BW_AND_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_XOR_SPEC_TMPVAR_CV): - ZEND_BW_XOR_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BOOL_XOR_SPEC_TMPVAR_CV): - ZEND_BOOL_XOR_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV): - ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV): - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV): - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_LIST_SPEC_TMPVAR_CV): - ZEND_FETCH_LIST_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMPVAR_CV): - ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV): - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CASE_SPEC_TMPVAR_CV): - ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV): - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV): - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CV): - ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_SPEC_TMPVAR_TMPVAR): - ZEND_ADD_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SUB_SPEC_TMPVAR_TMPVAR): - ZEND_SUB_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_MUL_SPEC_TMPVAR_TMPVAR): - ZEND_MUL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_DIV_SPEC_TMPVAR_TMPVAR): - ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_MOD_SPEC_TMPVAR_TMPVAR): - ZEND_MOD_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SL_SPEC_TMPVAR_TMPVAR): - ZEND_SL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SR_SPEC_TMPVAR_TMPVAR): - ZEND_SR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POW_SPEC_TMPVAR_TMPVAR): - ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CONCAT_SPEC_TMPVAR_TMPVAR): - ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR): - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR): - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_SPEC_TMPVAR_TMPVAR): - ZEND_IS_SMALLER_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_TMPVAR): - ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR): - ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_OR_SPEC_TMPVAR_TMPVAR): - ZEND_BW_OR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_AND_SPEC_TMPVAR_TMPVAR): - ZEND_BW_AND_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BW_XOR_SPEC_TMPVAR_TMPVAR): - ZEND_BW_XOR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR): - ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR): - ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR): - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR): - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR): - ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR): - ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR): - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CASE_SPEC_TMPVAR_TMPVAR): - ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR): - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR): - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR): - ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED): - ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED): - ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED): - ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_USED): - ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED): - ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED): - ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED): - ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED): - ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED): - ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_USED): - ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED): - ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED): - ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV): - ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POST_INC_LONG_SPEC_TMPVARCV): - ZEND_POST_INC_LONG_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POST_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV): - ZEND_POST_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV): - ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POST_DEC_LONG_SPEC_TMPVARCV): - ZEND_POST_DEC_LONG_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POST_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV): - ZEND_POST_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV): - ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV): - ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST): - ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SUB_LONG_SPEC_TMPVARCV_CONST): - ZEND_SUB_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST): - ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST): - ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ): - ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ): - ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST): - ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ): - ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ): - ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST): - ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ): - ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ): - ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST): - ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ): - ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ): - ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV): - ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV): - ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV): - ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV): - ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV): - ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV): - ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV): - ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV): - ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV): - ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV): - ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ): - ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ): - ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV): - ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ): - ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ): - ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV): - ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ): - ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ): - ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV): - ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ): - ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ): - ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV): - ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ): - ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ): - ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV): - ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ): - ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ): - ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV): - ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ): - ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ): - ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV): - ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ): - ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ): - ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(HYBRID_HALT): execute_data = orig_execute_data; opline = orig_opline; @@ -63767,7 +62423,7 @@ ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value) void zend_init_opcodes_handlers(void) { - static const void *labels[] = { + static const void * const labels[] = { ZEND_NOP_SPEC_HANDLER, ZEND_ADD_SPEC_CONST_CONST_HANDLER, ZEND_ADD_SPEC_CONST_TMPVAR_HANDLER, @@ -63820,20 +62476,20 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_SUB_SPEC_CV_CV_HANDLER, ZEND_MUL_SPEC_CONST_CONST_HANDLER, - ZEND_MUL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_MUL_SPEC_CONST_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_MUL_SPEC_CONST_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_MUL_SPEC_TMPVAR_CONST_HANDLER, ZEND_MUL_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_MUL_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_MUL_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_MUL_SPEC_TMPVAR_CONST_HANDLER, ZEND_MUL_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_MUL_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_MUL_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -63970,20 +62626,20 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_CONCAT_SPEC_CV_CV_HANDLER, ZEND_BW_OR_SPEC_CONST_CONST_HANDLER, - ZEND_BW_OR_SPEC_CONST_TMPVAR_HANDLER, - ZEND_BW_OR_SPEC_CONST_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_BW_OR_SPEC_CONST_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_BW_OR_SPEC_TMPVAR_CONST_HANDLER, ZEND_BW_OR_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_BW_OR_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_BW_OR_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_BW_OR_SPEC_TMPVAR_CONST_HANDLER, ZEND_BW_OR_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_BW_OR_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_BW_OR_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -63995,20 +62651,20 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_BW_OR_SPEC_CV_CV_HANDLER, ZEND_BW_AND_SPEC_CONST_CONST_HANDLER, - ZEND_BW_AND_SPEC_CONST_TMPVAR_HANDLER, - ZEND_BW_AND_SPEC_CONST_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_BW_AND_SPEC_CONST_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_BW_AND_SPEC_TMPVAR_CONST_HANDLER, ZEND_BW_AND_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_BW_AND_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_BW_AND_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_BW_AND_SPEC_TMPVAR_CONST_HANDLER, ZEND_BW_AND_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_BW_AND_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_BW_AND_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -64020,20 +62676,20 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_BW_AND_SPEC_CV_CV_HANDLER, ZEND_BW_XOR_SPEC_CONST_CONST_HANDLER, - ZEND_BW_XOR_SPEC_CONST_TMPVAR_HANDLER, - ZEND_BW_XOR_SPEC_CONST_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_BW_XOR_SPEC_CONST_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_BW_XOR_SPEC_TMPVAR_CONST_HANDLER, ZEND_BW_XOR_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_BW_XOR_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_BW_XOR_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_BW_XOR_SPEC_TMPVAR_CONST_HANDLER, ZEND_BW_XOR_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_BW_XOR_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_BW_XOR_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -64055,20 +62711,20 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_BOOL_NOT_SPEC_CV_HANDLER, ZEND_BOOL_XOR_SPEC_CONST_CONST_HANDLER, - ZEND_BOOL_XOR_SPEC_CONST_TMPVAR_HANDLER, - ZEND_BOOL_XOR_SPEC_CONST_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_BOOL_XOR_SPEC_CONST_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER, ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_BOOL_XOR_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER, ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_BOOL_XOR_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -64080,20 +62736,20 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER, ZEND_IS_IDENTICAL_SPEC_CONST_CONST_HANDLER, - ZEND_IS_IDENTICAL_SPEC_CONST_TMP_HANDLER, - ZEND_IS_IDENTICAL_SPEC_CONST_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_IDENTICAL_SPEC_CONST_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HANDLER, ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HANDLER, - ZEND_IS_IDENTICAL_SPEC_TMP_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_IDENTICAL_SPEC_TMP_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER, ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER, ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_IDENTICAL_SPEC_VAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -64105,20 +62761,20 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLER, ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_CONST_TMP_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_HANDLER, ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_TMP_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_HANDLER, ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_HANDLER, ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -64130,20 +62786,20 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HANDLER, ZEND_IS_EQUAL_SPEC_CONST_CONST_HANDLER, - ZEND_IS_EQUAL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_IS_EQUAL_SPEC_CONST_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_EQUAL_SPEC_CONST_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -64155,20 +62811,20 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER, ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CONST_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CONST_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_HANDLER, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_HANDLER, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -65655,16 +64311,16 @@ void zend_init_opcodes_handlers(void) ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_TMP_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_TMP_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_TMP_CV_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER, @@ -66050,31 +64706,31 @@ void zend_init_opcodes_handlers(void) ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER, - ZEND_FETCH_LIST_SPEC_CONST_CONST_HANDLER, - ZEND_FETCH_LIST_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FETCH_LIST_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_LIST_R_SPEC_CONST_CONST_HANDLER, + ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_LIST_SPEC_CONST_CV_HANDLER, - ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_LIST_R_SPEC_CONST_CV_HANDLER, + ZEND_FETCH_LIST_R_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FETCH_LIST_R_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_LIST_R_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_LIST_SPEC_TMPVAR_CV_HANDLER, - ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_LIST_R_SPEC_TMPVAR_CV_HANDLER, + ZEND_FETCH_LIST_R_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FETCH_LIST_R_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_LIST_R_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_LIST_SPEC_TMPVAR_CV_HANDLER, + ZEND_FETCH_LIST_R_SPEC_TMPVAR_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_LIST_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_LIST_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_LIST_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_LIST_R_SPEC_CV_CONST_HANDLER, + ZEND_FETCH_LIST_R_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_LIST_R_SPEC_CV_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_LIST_SPEC_CV_CV_HANDLER, + ZEND_FETCH_LIST_R_SPEC_CV_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -67675,16 +66331,41 @@ void zend_init_opcodes_handlers(void) ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, - ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_LIST_W_SPEC_VAR_CONST_HANDLER, + ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_LIST_W_SPEC_VAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_LIST_W_SPEC_CV_CONST_HANDLER, + ZEND_FETCH_LIST_W_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_LIST_W_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_LIST_W_SPEC_CV_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, - ZEND_NULL_HANDLER, + ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, @@ -67694,22 +66375,22 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, - ZEND_ADD_LONG_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_ADD_LONG_SPEC_CONST_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, - ZEND_ADD_LONG_SPEC_CONST_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_HANDLER, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, - ZEND_NULL_HANDLER, + ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_HANDLER, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, @@ -67719,22 +66400,22 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_HANDLER, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, - ZEND_ADD_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_ADD_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, - ZEND_ADD_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, - ZEND_NULL_HANDLER, + ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, @@ -67744,7 +66425,7 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, @@ -67825,16 +66506,16 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, - ZEND_MUL_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_MUL_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, - ZEND_MUL_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, - ZEND_NULL_HANDLER, + ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, @@ -67844,22 +66525,22 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, - ZEND_MUL_LONG_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_MUL_LONG_SPEC_CONST_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, - ZEND_MUL_LONG_SPEC_CONST_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_HANDLER, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, - ZEND_NULL_HANDLER, + ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_HANDLER, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, @@ -67869,22 +66550,22 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_HANDLER, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, - ZEND_MUL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_MUL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, - ZEND_MUL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, - ZEND_NULL_HANDLER, + ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, @@ -67894,7 +66575,7 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, @@ -67902,21 +66583,21 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, - ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, - ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, - ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, - ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, @@ -67929,9 +66610,9 @@ void zend_init_opcodes_handlers(void) ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, @@ -67959,9 +66640,9 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, @@ -67977,21 +66658,21 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, - ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, - ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, - ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, - ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, @@ -68004,9 +66685,9 @@ void zend_init_opcodes_handlers(void) ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, @@ -68034,9 +66715,9 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, @@ -68052,21 +66733,21 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, - ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, - ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, - ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, - ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, @@ -68079,9 +66760,9 @@ void zend_init_opcodes_handlers(void) ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, @@ -68109,9 +66790,9 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, @@ -68127,21 +66808,21 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, - ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, - ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, - ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, - ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, - ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, @@ -68154,9 +66835,9 @@ void zend_init_opcodes_handlers(void) ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, @@ -68184,9 +66865,9 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, @@ -68695,22 +67376,22 @@ void zend_init_opcodes_handlers(void) 0, 1 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 26 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 51 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 51 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE, 76 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 101 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 126 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 151 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 176 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 201 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 226 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 251 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 201 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE, + 226 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE, + 251 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE, 276 | SPEC_RULE_OP1, 281 | SPEC_RULE_OP1, - 286 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 311 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 336 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 361 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 386 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 286 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE, + 311 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE, + 336 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE, + 361 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE, + 386 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE, 411 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 436 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 461 | SPEC_RULE_OP1, @@ -68792,7 +67473,7 @@ void zend_init_opcodes_handlers(void) 2257 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 2282 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 2307 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 4921, + 4946, 2332, 2333, 2334, @@ -68877,7 +67558,7 @@ void zend_init_opcodes_handlers(void) 3531 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3556 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3581 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 4921, + 4946, 3606 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3631 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3656 | SPEC_RULE_OP1 | SPEC_RULE_OP2, @@ -68890,7 +67571,8 @@ void zend_init_opcodes_handlers(void) 3831 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3856 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3881 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 4921 + 3906 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 4946 }; #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) zend_opcode_handler_funcs = labels; @@ -69015,10 +67697,12 @@ static const void *zend_vm_get_opcode_handler_ex(uint32_t spec, const zend_op* o return zend_opcode_handlers[(spec & SPEC_START_MASK) + offset]; } +#if ZEND_VM_KIND != ZEND_VM_KIND_HYBRID static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op) { return zend_vm_get_opcode_handler_ex(zend_spec_handlers[opcode], op); } +#endif #if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID static const void *zend_vm_get_opcode_handler_func(zend_uchar opcode, const zend_op* op) @@ -69072,7 +67756,14 @@ static const void *zend_vm_get_opcode_handler_func(zend_uchar opcode, const zend ZEND_API void zend_vm_set_opcode_handler(zend_op* op) { - op->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], op); + uint32_t spec = zend_spec_handlers[op->opcode]; + + if (spec & SPEC_RULE_COMMUTATIVE) { + if (op->op1_type < op->op2_type) { + zend_swap_operands(op); + } + } + op->handler = zend_vm_get_opcode_handler_ex(spec, op); } ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint32_t op2_info, uint32_t res_info) @@ -69085,24 +67776,24 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3906 | SPEC_RULE_OP1 | SPEC_RULE_OP2; - if (op->op1_type > op->op2_type) { + spec = 3931 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + if (op->op1_type < op->op2_type) { zend_swap_operands(op); } } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3931 | SPEC_RULE_OP1 | SPEC_RULE_OP2; - if (op->op1_type > op->op2_type) { + spec = 3956 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + if (op->op1_type < op->op2_type) { zend_swap_operands(op); } } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3956 | SPEC_RULE_OP1 | SPEC_RULE_OP2; - if (op->op1_type > op->op2_type) { + spec = 3981 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + if (op->op1_type < op->op2_type) { zend_swap_operands(op); } } @@ -69112,82 +67803,70 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3981 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 4006 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4006 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 4031 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4031 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 4056 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_MUL: + if (op->op1_type < op->op2_type) { + zend_swap_operands(op); + } if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4056 | SPEC_RULE_OP1 | SPEC_RULE_OP2; - if (op->op1_type > op->op2_type) { - zend_swap_operands(op); - } + spec = 4081 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4081 | SPEC_RULE_OP1 | SPEC_RULE_OP2; - if (op->op1_type > op->op2_type) { - zend_swap_operands(op); - } + spec = 4106 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4106 | SPEC_RULE_OP1 | SPEC_RULE_OP2; - if (op->op1_type > op->op2_type) { - zend_swap_operands(op); - } + spec = 4131 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_EQUAL: + if (op->op1_type < op->op2_type) { + zend_swap_operands(op); + } if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4131 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; - if (op->op1_type > op->op2_type) { - zend_swap_operands(op); - } + spec = 4156 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4206 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; - if (op->op1_type > op->op2_type) { - zend_swap_operands(op); - } + spec = 4231 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_EQUAL: + if (op->op1_type < op->op2_type) { + zend_swap_operands(op); + } if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4281 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; - if (op->op1_type > op->op2_type) { - zend_swap_operands(op); - } + spec = 4306 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4356 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; - if (op->op1_type > op->op2_type) { - zend_swap_operands(op); - } + spec = 4381 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_SMALLER: @@ -69195,12 +67874,12 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4431 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4456 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4506 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4531 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_IS_SMALLER_OR_EQUAL: @@ -69208,75 +67887,85 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4581 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4606 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 4656 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 4681 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_QM_ASSIGN: if (op1_info == MAY_BE_DOUBLE) { - spec = 4821 | SPEC_RULE_OP1; + spec = 4846 | SPEC_RULE_OP1; } else if (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE)))) { - spec = 4826 | SPEC_RULE_OP1; + spec = 4851 | SPEC_RULE_OP1; } break; case ZEND_PRE_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4731 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4756 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 4741 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4766 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { - spec = 4751 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4776 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } break; case ZEND_PRE_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4761 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4786 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 4771 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4796 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { - spec = 4781 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + spec = 4806 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; } break; case ZEND_POST_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4791 | SPEC_RULE_OP1; + spec = 4816 | SPEC_RULE_OP1; } else if (op1_info == MAY_BE_LONG) { - spec = 4796 | SPEC_RULE_OP1; + spec = 4821 | SPEC_RULE_OP1; } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { - spec = 4801 | SPEC_RULE_OP1; + spec = 4826 | SPEC_RULE_OP1; } break; case ZEND_POST_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 4806 | SPEC_RULE_OP1; + spec = 4831 | SPEC_RULE_OP1; } else if (op1_info == MAY_BE_LONG) { - spec = 4811 | SPEC_RULE_OP1; + spec = 4836 | SPEC_RULE_OP1; } else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) { - spec = 4816 | SPEC_RULE_OP1; + spec = 4841 | SPEC_RULE_OP1; } break; case ZEND_SEND_VAR_EX: if ((op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 4861 | SPEC_RULE_OP1 | SPEC_RULE_QUICK_ARG; + spec = 4886 | SPEC_RULE_OP1 | SPEC_RULE_QUICK_ARG; } break; case ZEND_FE_FETCH_R: if (op->op2_type == IS_CV && (op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) { - spec = 4871 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_RETVAL; + spec = 4896 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_RETVAL; } break; case ZEND_FETCH_DIM_R: if (!(op2_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) { - spec = 4831 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 4856 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_SEND_VAR: if ((op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 4856 | SPEC_RULE_OP1; + spec = 4881 | SPEC_RULE_OP1; + } + break; + case ZEND_BW_OR: + case ZEND_BW_AND: + case ZEND_BW_XOR: + case ZEND_BOOL_XOR: + case ZEND_IS_IDENTICAL: + case ZEND_IS_NOT_IDENTICAL: + if (op->op1_type < op->op2_type) { + zend_swap_operands(op); } break; default: diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 69c8e19c1a..4f4ad4c7b2 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -84,7 +84,7 @@ $vm_op_flags = array( "ZEND_VM_EXT_CONST_FETCH" => 0x06000000, "ZEND_VM_EXT_TYPE" => 0x07000000, "ZEND_VM_EXT_EVAL" => 0x08000000, - // unused 0x09000000, + "ZEND_VM_EXT_TYPE_MASK" => 0x09000000, // unused 0x0a000000, "ZEND_VM_EXT_SRC" => 0x0b000000, // unused 0x0c000000, @@ -125,6 +125,7 @@ $vm_ext_decode = array( "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, "ARG_NUM" => ZEND_VM_EXT_ARG_NUM, "REF" => ZEND_VM_EXT_REF, @@ -150,12 +151,12 @@ $op_types = array( $op_types_ex = array( "ANY", "CONST", + "TMPVARCV", + "TMPVAR", "TMP", "VAR", "UNUSED", "CV", - "TMPVAR", - "TMPVARCV", ); $prefix = array( @@ -239,7 +240,7 @@ $op1_get_zval_ptr = array( "ANY" => "get_zval_ptr(opline->op1_type, opline->op1, &free_op1, \\1)", "TMP" => "_get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", "VAR" => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", - "CONST" => "EX_CONSTANT(opline->op1)", + "CONST" => "RT_CONSTANT(opline, opline->op1)", "UNUSED" => "NULL", "CV" => "_get_zval_ptr_cv_\\1(opline->op1.var EXECUTE_DATA_CC)", "TMPVAR" => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", @@ -250,7 +251,7 @@ $op2_get_zval_ptr = array( "ANY" => "get_zval_ptr(opline->op2_type, opline->op2, &free_op2, \\1)", "TMP" => "_get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", "VAR" => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", - "CONST" => "EX_CONSTANT(opline->op2)", + "CONST" => "RT_CONSTANT(opline, opline->op2)", "UNUSED" => "NULL", "CV" => "_get_zval_ptr_cv_\\1(opline->op2.var EXECUTE_DATA_CC)", "TMPVAR" => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", @@ -283,7 +284,7 @@ $op1_get_zval_ptr_deref = array( "ANY" => "get_zval_ptr_deref(opline->op1_type, opline->op1, &free_op1, \\1)", "TMP" => "_get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", "VAR" => "_get_zval_ptr_var_deref(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", - "CONST" => "EX_CONSTANT(opline->op1)", + "CONST" => "RT_CONSTANT(opline, opline->op1)", "UNUSED" => "NULL", "CV" => "_get_zval_ptr_cv_deref_\\1(opline->op1.var EXECUTE_DATA_CC)", "TMPVAR" => "???", @@ -294,7 +295,7 @@ $op2_get_zval_ptr_deref = array( "ANY" => "get_zval_ptr_deref(opline->op2_type, opline->op2, &free_op2, \\1)", "TMP" => "_get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", "VAR" => "_get_zval_ptr_var_deref(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", - "CONST" => "EX_CONSTANT(opline->op2)", + "CONST" => "RT_CONSTANT(opline, opline->op2)", "UNUSED" => "NULL", "CV" => "_get_zval_ptr_cv_deref_\\1(opline->op2.var EXECUTE_DATA_CC)", "TMPVAR" => "???", @@ -305,7 +306,7 @@ $op1_get_zval_ptr_undef = array( "ANY" => "get_zval_ptr_undef(opline->op1_type, opline->op1, &free_op1, \\1)", "TMP" => "_get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", "VAR" => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", - "CONST" => "EX_CONSTANT(opline->op1)", + "CONST" => "RT_CONSTANT(opline, opline->op1)", "UNUSED" => "NULL", "CV" => "_get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC)", "TMPVAR" => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", @@ -316,7 +317,7 @@ $op2_get_zval_ptr_undef = array( "ANY" => "get_zval_ptr_undef(opline->op2_type, opline->op2, &free_op2, \\1)", "TMP" => "_get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", "VAR" => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", - "CONST" => "EX_CONSTANT(opline->op2)", + "CONST" => "RT_CONSTANT(opline, opline->op2)", "UNUSED" => "NULL", "CV" => "_get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC)", "TMPVAR" => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", @@ -349,7 +350,7 @@ $op1_get_obj_zval_ptr = array( "ANY" => "get_obj_zval_ptr(opline->op1_type, opline->op1, &free_op1, \\1)", "TMP" => "_get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", "VAR" => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", - "CONST" => "EX_CONSTANT(opline->op1)", + "CONST" => "RT_CONSTANT(opline, opline->op1)", "UNUSED" => "_get_obj_zval_ptr_unused(EXECUTE_DATA_C)", "CV" => "_get_zval_ptr_cv_\\1(opline->op1.var EXECUTE_DATA_CC)", "TMPVAR" => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", @@ -360,7 +361,7 @@ $op2_get_obj_zval_ptr = array( "ANY" => "get_obj_zval_ptr(opline->op2_type, opline->op2, &free_op2, \\1)", "TMP" => "_get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", "VAR" => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", - "CONST" => "EX_CONSTANT(opline->op2)", + "CONST" => "RT_CONSTANT(opline, opline->op2)", "UNUSED" => "_get_obj_zval_ptr_unused(EXECUTE_DATA_C)", "CV" => "_get_zval_ptr_cv_\\1(opline->op2.var EXECUTE_DATA_CC)", "TMPVAR" => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", @@ -371,7 +372,7 @@ $op1_get_obj_zval_ptr_undef = array( "ANY" => "get_obj_zval_ptr_undef(opline->op1_type, opline->op1, &free_op1, \\1)", "TMP" => "_get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", "VAR" => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", - "CONST" => "EX_CONSTANT(opline->op1)", + "CONST" => "RT_CONSTANT(opline, opline->op1)", "UNUSED" => "_get_obj_zval_ptr_unused(EXECUTE_DATA_C)", "CV" => "_get_zval_ptr_cv_undef(opline->op1.var EXECUTE_DATA_CC)", "TMPVAR" => "_get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", @@ -382,7 +383,7 @@ $op2_get_obj_zval_ptr_undef = array( "ANY" => "get_obj_zval_ptr_undef(opline->op2_type, opline->op2, &free_op2, \\1)", "TMP" => "_get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", "VAR" => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", - "CONST" => "EX_CONSTANT(opline->op2)", + "CONST" => "RT_CONSTANT(opline, opline->op2)", "UNUSED" => "_get_obj_zval_ptr_unused(EXECUTE_DATA_C)", "CV" => "_get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC)", "TMPVAR" => "_get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", @@ -393,7 +394,7 @@ $op1_get_obj_zval_ptr_deref = array( "ANY" => "get_obj_zval_ptr(opline->op1_type, opline->op1, &free_op1, \\1)", "TMP" => "_get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", "VAR" => "_get_zval_ptr_var_deref(opline->op1.var, &free_op1 EXECUTE_DATA_CC)", - "CONST" => "EX_CONSTANT(opline->op1)", + "CONST" => "RT_CONSTANT(opline, opline->op1)", "UNUSED" => "_get_obj_zval_ptr_unused(EXECUTE_DATA_C)", "CV" => "_get_zval_ptr_cv_deref_\\1(opline->op1.var EXECUTE_DATA_CC)", "TMPVAR" => "???", @@ -404,7 +405,7 @@ $op2_get_obj_zval_ptr_deref = array( "ANY" => "get_obj_zval_ptr(opline->op2_type, opline->op2, &free_op2, \\1)", "TMP" => "_get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", "VAR" => "_get_zval_ptr_var_deref(opline->op2.var, &free_op2 EXECUTE_DATA_CC)", - "CONST" => "EX_CONSTANT(opline->op2)", + "CONST" => "RT_CONSTANT(opline, opline->op2)", "UNUSED" => "_get_obj_zval_ptr_unused(EXECUTE_DATA_C)", "CV" => "_get_zval_ptr_cv_deref_\\1(opline->op2.var EXECUTE_DATA_CC)", "TMPVAR" => "???", @@ -555,10 +556,10 @@ $op_data_type = array( ); $op_data_get_zval_ptr = array( - "ANY" => "get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, &free_op_data, \\1)", + "ANY" => "get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data)", "TMP" => "_get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC)", "VAR" => "_get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC)", - "CONST" => "EX_CONSTANT((opline+1)->op1)", + "CONST" => "RT_CONSTANT((opline+1), (opline+1)->op1)", "UNUSED" => "NULL", "CV" => "_get_zval_ptr_cv_\\1((opline+1)->op1.var EXECUTE_DATA_CC)", "TMPVAR" => "_get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC)", @@ -566,10 +567,10 @@ $op_data_get_zval_ptr = array( ); $op_data_get_zval_ptr_deref = array( - "ANY" => "get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, &free_op_data, \\1)", + "ANY" => "get_op_data_zval_ptr_deref_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data)", "TMP" => "_get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC)", "VAR" => "_get_zval_ptr_var_deref((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC)", - "CONST" => "EX_CONSTANT((opline+1)->op1)", + "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" => "???", @@ -632,13 +633,33 @@ function helper_name($name, $spec, $op1, $op2, $extra_spec) { if (isset($helpers[$name])) { // If we haven't helper with specified spicialized operands then // using unspecialized helper - if (!isset($helpers[$name]["op1"][$op1]) && - isset($helpers[$name]["op1"]["ANY"])) { - $op1 = "ANY"; + 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]) && - isset($helpers[$name]["op2"]["ANY"])) { - $op2 = "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"])) { @@ -655,13 +676,39 @@ function opcode_name($name, $spec, $op1, $op2) { $opcode = $opcodes[$opnames[$name]]; // If we haven't helper with specified spicialized operands then // using unspecialized helper - if (!isset($opcode["op1"][$op1]) && - isset($opcode["op1"]["ANY"])) { - $op1 = "ANY"; + 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]) && - isset($opcode["op2"]["ANY"])) { - $op2 = "ANY"; + 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 unkonwn handler in unreachable code */ + return "ZEND_NULL"; + } } } return $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]; @@ -959,7 +1006,7 @@ function skip_extra_spec_function($op1, $op2, $extra_spec) { } if (isset($extra_spec["COMMUTATIVE"]) && - $commutative_order[$op1] > $commutative_order[$op2]) { + $commutative_order[$op1] < $commutative_order[$op2]) { // Skip duplicate commutative handlers return true; } @@ -1115,7 +1162,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array() $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); + $specs[$num] .= " | " . implode(" | ", $flags); } if ($num >= 256) { $opcodes[$num]['spec_code'] = $specs[$num]; @@ -1416,6 +1463,9 @@ function extra_spec_flags($extra_spec) { if (isset($extra_spec["DIM_OBJ"])) { $s[] = "SPEC_RULE_DIM_OBJ"; } + if (isset($extra_spec["COMMUTATIVE"])) { + $s[] = "SPEC_RULE_COMMUTATIVE"; + } return $s; } @@ -1577,17 +1627,20 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) out($f,"#define SPEC_RULE_QUICK_ARG 0x00100000\n"); out($f,"#define SPEC_RULE_SMART_BRANCH 0x00200000\n"); out($f,"#define SPEC_RULE_DIM_OBJ 0x00400000\n"); + out($f,"#define SPEC_RULE_COMMUTATIVE 0x00800000\n"); out($f,"\n"); out($f,"static const uint32_t *zend_spec_handlers;\n"); - out($f,"static const void **zend_opcode_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 **zend_opcode_handler_funcs;\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,"static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op);\n\n"); + out($f,"#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID)\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"); @@ -1674,12 +1727,15 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) 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() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\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() opline = EG(current_execute_data)->opline; return 1\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"); @@ -1691,7 +1747,8 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) 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);"); + 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: @@ -1718,7 +1775,8 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) 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() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\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"); @@ -1754,7 +1812,8 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) } 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() execute_data = EG(current_execute_data); LOAD_OPLINE(); ZEND_VM_INTERRUPT_CHECK(); ZEND_VM_CONTINUE()\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"); @@ -1804,7 +1863,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) } $prolog = $m[1]; out($f,$prolog."if (UNEXPECTED(execute_data == NULL)) {\n"); - out($f,$prolog."\tstatic const void* labels[] = {\n"); + out($f,$prolog."\tstatic const void * const labels[] = {\n"); gen_labels($f, $spec, ZEND_VM_KIND_GOTO, $prolog."\t\t", $specs); out($f,$prolog."\t};\n"); out($f,$prolog."\tzend_opcode_handlers = (const void **) labels;\n"); @@ -1919,7 +1978,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) out($f,$prolog."zend_spec_handlers = specs;\n"); out($f,$prolog.$executor_name."_ex(NULL);\n"); } else { - out($f,$prolog."static const void *labels[] = {\n"); + out($f,$prolog."static const void * const labels[] = {\n"); gen_labels($f, $spec, ZEND_VM_KIND_CALL, $prolog."\t", $specs, $switch_labels); out($f,$prolog."};\n"); out($f,$prolog."static const uint32_t specs[] = {\n"); @@ -2140,7 +2199,7 @@ function gen_vm($def, $skel) { } $opcodes[$orig_code]['type_spec'][$code] = $condition; $used_extra_spec["TYPE"] = 1; - $opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>"","flags"=>$flags,"hot"=>$hot); + $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"])) { @@ -2444,6 +2503,7 @@ function gen_vm($def, $skel) { out($f, "\treturn zend_opcode_handlers[(spec & SPEC_START_MASK) + offset];\n"); } out($f, "}\n\n"); + out($f, "#if ZEND_VM_KIND != ZEND_VM_KIND_HYBRID\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) { @@ -2451,7 +2511,8 @@ function gen_vm($def, $skel) { } else { out($f, "\treturn zend_vm_get_opcode_handler_ex(zend_spec_handlers[opcode], op);\n"); } - out($f, "}\n\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 @@ -2522,7 +2583,17 @@ function gen_vm($def, $skel) { // Generate zend_vm_get_opcode_handler() function out($f, "ZEND_API void zend_vm_set_opcode_handler(zend_op* op)\n"); out($f, "{\n"); - out($f, "\top->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], op);\n"); + if (!ZEND_VM_SPEC) { + out($f, "\top->handler = zend_vm_get_opcode_handler(op->opcode, op);\n"); + } else { + out($f, "\tuint32_t spec = zend_spec_handlers[op->opcode];\n\n"); + out($f, "\tif (spec & SPEC_RULE_COMMUTATIVE) {\n"); + out($f, "\t\tif (op->op1_type < op->op2_type) {\n"); + out($f, "\t\t\tzend_swap_operands(op);\n"); + out($f, "\t\t}\n"); + out($f, "\t}\n"); + out($f, "\top->handler = zend_vm_get_opcode_handler_ex(spec, op);\n"); + } out($f, "}\n\n"); // Generate zend_vm_set_opcode_handler_ex() function @@ -2539,6 +2610,11 @@ function gen_vm($def, $skel) { 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); @@ -2555,8 +2631,8 @@ function gen_vm($def, $skel) { out($f, "\t\t\t\t}\n"); } out($f, "\t\t\t\tspec = ${spec_dsc['spec_code']};\n"); - if (isset($spec_dsc["spec"]["COMMUTATIVE"])) { - out($f, "\t\t\t\tif (op->op1_type > op->op2_type) {\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"); } @@ -2567,6 +2643,22 @@ function gen_vm($def, $skel) { 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\tdefault:\n"); out($f, "\t\t\tbreak;\n"); out($f, "\t}\n"); @@ -2657,11 +2749,13 @@ function gen_vm($def, $skel) { 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"); diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index ecfe4645fa..44b8a2df19 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -21,7 +21,7 @@ #include <stdio.h> #include <zend.h> -static const char *zend_vm_opcodes_names[198] = { +static const char *zend_vm_opcodes_names[199] = { "ZEND_NOP", "ZEND_ADD", "ZEND_SUB", @@ -120,7 +120,7 @@ static const char *zend_vm_opcodes_names[198] = { "ZEND_FETCH_UNSET", "ZEND_FETCH_DIM_UNSET", "ZEND_FETCH_OBJ_UNSET", - "ZEND_FETCH_LIST", + "ZEND_FETCH_LIST_R", "ZEND_FETCH_CONSTANT", NULL, "ZEND_EXT_STMT", @@ -220,28 +220,29 @@ static const char *zend_vm_opcodes_names[198] = { "ZEND_FUNC_GET_ARGS", "ZEND_UNSET_CV", "ZEND_ISSET_ISEMPTY_CV", + "ZEND_FETCH_LIST_W", }; -static uint32_t zend_vm_opcodes_flags[198] = { +static uint32_t zend_vm_opcodes_flags[199] = { 0x00000000, 0x00000707, 0x00000707, + 0x80000707, 0x00000707, 0x00000707, 0x00000707, 0x00000707, 0x00000707, - 0x00000707, - 0x00000707, - 0x00000707, - 0x00000707, + 0x80000707, + 0x80000707, + 0x80000707, 0x00000007, 0x00000007, - 0x00000707, - 0x00000303, - 0x00000303, - 0x00000707, - 0x00000707, + 0x80000707, + 0x80000303, + 0x80000303, + 0x80000707, + 0x80000707, 0x00000707, 0x00000707, 0x07000003, @@ -305,7 +306,7 @@ static uint32_t zend_vm_opcodes_flags[198] = { 0x00000007, 0x00010107, 0x00000707, - 0x00000753, + 0x00000757, 0x00010107, 0x00006701, 0x00000751, @@ -346,7 +347,7 @@ static uint32_t zend_vm_opcodes_flags[198] = { 0x00001003, 0x00000007, 0x00000003, - 0x07000003, + 0x09000003, 0x00000103, 0x00002003, 0x03000001, @@ -421,6 +422,7 @@ static uint32_t zend_vm_opcodes_flags[198] = { 0x00000103, 0x00000101, 0x00020101, + 0x00000701, }; ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) { diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 3be364150f..7956d5fee4 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -60,6 +60,7 @@ #define ZEND_VM_EXT_CONST_FETCH 0x06000000 #define ZEND_VM_EXT_TYPE 0x07000000 #define ZEND_VM_EXT_EVAL 0x08000000 +#define ZEND_VM_EXT_TYPE_MASK 0x09000000 #define ZEND_VM_EXT_SRC 0x0b000000 #define ZEND_VM_NO_CONST_CONST 0x40000000 #define ZEND_VM_COMMUTATIVE 0x80000000 @@ -171,7 +172,7 @@ END_EXTERN_C() #define ZEND_FETCH_UNSET 95 #define ZEND_FETCH_DIM_UNSET 96 #define ZEND_FETCH_OBJ_UNSET 97 -#define ZEND_FETCH_LIST 98 +#define ZEND_FETCH_LIST_R 98 #define ZEND_FETCH_CONSTANT 99 #define ZEND_EXT_STMT 101 #define ZEND_EXT_FCALL_BEGIN 102 @@ -269,7 +270,8 @@ END_EXTERN_C() #define ZEND_FUNC_GET_ARGS 195 #define ZEND_UNSET_CV 196 #define ZEND_ISSET_ISEMPTY_CV 197 +#define ZEND_FETCH_LIST_W 198 -#define ZEND_VM_LAST_OPCODE 197 +#define ZEND_VM_LAST_OPCODE 198 #endif |