diff options
Diffstat (limited to 'Zend')
120 files changed, 26389 insertions, 11077 deletions
diff --git a/Zend/tests/add_006.phpt b/Zend/tests/add_006.phpt index d56df2f329..fe1c0830e2 100644 --- a/Zend/tests/add_006.phpt +++ b/Zend/tests/add_006.phpt @@ -38,11 +38,19 @@ var_dump($c); echo "Done\n"; ?> --EXPECTF-- + +Warning: A non-numeric value encountered in %s on line %d int(75636) + +Notice: A non well formed numeric value encountered in %s on line %d int(951858) int(48550510) float(75661.68) + +Warning: A non-numeric value encountered in %s on line %d int(75636) + +Notice: A non well formed numeric value encountered in %s on line %d int(951858) int(48550510) float(75661.68) diff --git a/Zend/tests/add_007.phpt b/Zend/tests/add_007.phpt index 66f5405706..089b24ae0b 100644 --- a/Zend/tests/add_007.phpt +++ b/Zend/tests/add_007.phpt @@ -19,8 +19,13 @@ var_dump($c); echo "Done\n"; ?> --EXPECTF-- + +Warning: A non-numeric value encountered in %s on line %d + Exception: Unsupported operand types +Warning: A non-numeric value encountered in %s on line %d + Fatal error: Uncaught Error: Unsupported operand types in %s:%d Stack trace: #0 {main} diff --git a/Zend/tests/anon/013.phpt b/Zend/tests/anon/013.phpt new file mode 100644 index 0000000000..72ba3d61b7 --- /dev/null +++ b/Zend/tests/anon/013.phpt @@ -0,0 +1,15 @@ +--TEST-- +closure binding to anonymous class +--FILE-- +<?php +$class = new class {}; +$foo = function() { + return $this; +}; + +$closure = Closure::bind($foo, $class, $class); +var_dump($closure()); +?> +--EXPECTF-- +object(class@anonymous)#1 (0) { +} diff --git a/Zend/tests/anon/014.phpt b/Zend/tests/anon/014.phpt new file mode 100644 index 0000000000..cacac47857 --- /dev/null +++ b/Zend/tests/anon/014.phpt @@ -0,0 +1,16 @@ +--TEST-- +anonymous class trait binding +--FILE-- +<?php +trait TaskTrait { + function run() { + return 'Running...'; + } +} +$class = new class() { + use TaskTrait; +}; +var_dump($class->run()); +?> +--EXPECTF-- +string(10) "Running..." diff --git a/Zend/tests/bug29883.phpt b/Zend/tests/bug29883.phpt index c92f147ff7..b6ad99aeaf 100644 --- a/Zend/tests/bug29883.phpt +++ b/Zend/tests/bug29883.phpt @@ -3,7 +3,7 @@ Bug #29883 (isset gives invalid values on strings) --FILE-- <?php $x = "bug"; -var_dump(isset($x[-1])); +var_dump(isset($x[-10])); var_dump(isset($x["1"])); echo $x["1"]."\n"; ?> diff --git a/Zend/tests/bug31098.phpt b/Zend/tests/bug31098.phpt index 23cec9bbf4..31823a1aa5 100644 --- a/Zend/tests/bug31098.phpt +++ b/Zend/tests/bug31098.phpt @@ -18,7 +18,7 @@ var_dump(isset($a['b'])); $simpleString = "Bogus String Text"; echo isset($simpleString->wrong)?"bug\n":"ok\n"; echo isset($simpleString["wrong"])?"bug\n":"ok\n"; -echo isset($simpleString[-1])?"bug\n":"ok\n"; +echo isset($simpleString[-20])?"bug\n":"ok\n"; echo isset($simpleString[0])?"ok\n":"bug\n"; echo isset($simpleString["0"])?"ok\n":"bug\n"; echo isset($simpleString["16"])?"ok\n":"bug\n"; diff --git a/Zend/tests/bug41813.phpt b/Zend/tests/bug41813.phpt index 0bb693075a..9a609d09c8 100644 --- a/Zend/tests/bug41813.phpt +++ b/Zend/tests/bug41813.phpt @@ -9,7 +9,7 @@ $foo[0]->bar = "xyz"; echo "Done\n"; ?> --EXPECTF-- -Fatal error: Uncaught Error: Cannot use string offset as an array in %s:%d +Fatal error: Uncaught Error: Cannot use string offset as an object in %s:%d Stack trace: #0 {main} thrown in %s on line %d diff --git a/Zend/tests/bug49866.phpt b/Zend/tests/bug49866.phpt index 3d96a59cd5..0b7c224c01 100644 --- a/Zend/tests/bug49866.phpt +++ b/Zend/tests/bug49866.phpt @@ -7,7 +7,7 @@ $b = &$a[1]; $b = "f"; echo $a; --EXPECTF-- -Fatal error: Uncaught Error: Cannot create references to/from string offsets nor overloaded objects in %sbug49866.php:3 +Fatal error: Uncaught Error: Cannot create references to/from string offsets in %sbug49866.php:3 Stack trace: #0 {main} thrown in %sbug49866.php on line 3 diff --git a/Zend/tests/bug52879.phpt b/Zend/tests/bug52879.phpt index 0193be4b45..6c3232f32d 100644 --- a/Zend/tests/bug52879.phpt +++ b/Zend/tests/bug52879.phpt @@ -8,7 +8,7 @@ class MyClass { $this->myRef = $value; } } -$myGlobal=new MyClass($myGlobal); +$myGlobal=new MyClass(); $myGlobal->myRef=&$myGlobal; $myGlobal->myNonExistentProperty="ok\n"; echo $myGlobal; diff --git a/Zend/tests/bug62814.phpt b/Zend/tests/bug62814.phpt new file mode 100644 index 0000000000..6646aa283f --- /dev/null +++ b/Zend/tests/bug62814.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #62814: It is possible to stiffen child class members visibility +--FILE-- +<?php + +class A { + private function test() { } +} + +class B extends A { + protected function test() { } +} + +class C extends B { + private function test() { } +} + +?> +--EXPECTF-- +Fatal error: Access level to C::test() must be protected (as in class B) or weaker in %s on line %d diff --git a/Zend/tests/bug68652.phpt b/Zend/tests/bug68652.phpt index e86312ba63..8e54af2e34 100644 --- a/Zend/tests/bug68652.phpt +++ b/Zend/tests/bug68652.phpt @@ -28,6 +28,7 @@ class Bar { } public function __destruct() { + if (!isset(self::$instance)) return; Foo::getInstance(); } } diff --git a/Zend/tests/bug69989_2.phpt b/Zend/tests/bug69989_2.phpt new file mode 100644 index 0000000000..a6f320da3b --- /dev/null +++ b/Zend/tests/bug69989_2.phpt @@ -0,0 +1,42 @@ +--TEST-- +Collection of some cycles on unfinished generators +--FILE-- +<?php + +// CV +function gen1() { + $gen = yield; + yield; +} + +$gen = gen1(); +$gen->send($gen); + +// This +class Test { + public $gen; + public function gen2() { + yield; + } +} + +$test = new Test; +$test->gen = $test->gen2(); + +// Closure object +$gen3 = (function() use (&$gen3) { + yield; +})(); + +// Yield from array +function gen4() { + yield from [yield]; +} + +$gen = gen4(); +$gen->send($gen); + +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/bug69989_3.phpt b/Zend/tests/bug69989_3.phpt new file mode 100644 index 0000000000..260819197b --- /dev/null +++ b/Zend/tests/bug69989_3.phpt @@ -0,0 +1,44 @@ +--TEST-- +Generator cycle collection edge cases +--FILE-- +<?php + +// Extra args +function gen1() { + yield; +} +$obj = new stdClass; +$obj->gen = gen1($obj); + +// Symtable +function gen2() { + $varName = 'a'; + $$varName = yield; + yield; +} +$gen = gen2(); +$gen->send($gen); + +// Symtable indirect +function gen3() { + $varName = 'a'; + $$varName = 42; + $var = yield; + yield; +} +$gen = gen3(); +$gen->send($gen); + +// Yield from root +function gen4() { + yield from yield; +} +$gen = gen4(); +$gen2 = gen4($gen); +$gen2->send([1, 2, 3]); +$gen->send($gen2); + +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/bug70089.phpt b/Zend/tests/bug70089.phpt index c61db00c9e..e1884d9dac 100644 --- a/Zend/tests/bug70089.phpt +++ b/Zend/tests/bug70089.phpt @@ -34,4 +34,4 @@ try { string(36) "Cannot use string offset as an array" string(27) "Cannot unset string offsets" string(41) "Only variables can be passed by reference" -string(64) "Cannot increment/decrement overloaded objects nor string offsets" +string(41) "Cannot increment/decrement string offsets" diff --git a/Zend/tests/bug70918.phpt b/Zend/tests/bug70918.phpt new file mode 100644 index 0000000000..81e2192d8a --- /dev/null +++ b/Zend/tests/bug70918.phpt @@ -0,0 +1,47 @@ +--TEST-- +Bug #70918 (Segfault using static outside of class scope) +--FILE-- +<?php +try { + static::x; +} catch (Error $e) { + var_dump($e->getMessage()); +} + +try { + parent::x; +} catch (Error $e) { + var_dump($e->getMessage()); +} + +try { + self::x; +} catch (Error $e) { + var_dump($e->getMessage()); +} + +try { + new static; +} catch (Error $e) { + var_dump($e->getMessage()); +} + +try { + static::x(); +} catch (Error $e) { + var_dump($e->getMessage()); +} + +try { + static::$i; +} catch (Error $e) { + var_dump($e->getMessage()); +} +?> +--EXPECT-- +string(52) "Cannot access static:: when no class scope is active" +string(52) "Cannot access parent:: when no class scope is active" +string(50) "Cannot access self:: when no class scope is active" +string(52) "Cannot access static:: when no class scope is active" +string(52) "Cannot access static:: when no class scope is active" +string(52) "Cannot access static:: when no class scope is active" diff --git a/Zend/tests/bug71196.phpt b/Zend/tests/bug71196.phpt new file mode 100644 index 0000000000..ca25f9f4fc --- /dev/null +++ b/Zend/tests/bug71196.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #71196 (Memory leak with out-of-order live ranges) +--FILE-- +<?php +try { + $a = "1"; + [1, (y().$a.$a) . ($a.$a)]; +} catch (Error $e) { + var_dump($e->getMessage()); +} +?> +--EXPECT-- +string(30) "Call to undefined function y()" diff --git a/Zend/tests/bug71572.phpt b/Zend/tests/bug71572.phpt new file mode 100644 index 0000000000..4a823ec72f --- /dev/null +++ b/Zend/tests/bug71572.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #71572: String offset assignment from an empty string inserts null byte +--FILE-- +<?php + +$str = "abc"; +var_dump($str{0} = ""); +var_dump($str{1} = ""); +var_dump($str{3} = ""); +var_dump($str{10} = ""); +var_dump($str); +?> +==DONE== +--EXPECTF-- +Warning: Cannot assign an empty string to a string offset in %s on line %d +NULL + +Warning: Cannot assign an empty string to a string offset in %s on line %d +NULL + +Warning: Cannot assign an empty string to a string offset in %s on line %d +NULL + +Warning: Cannot assign an empty string to a string offset in %s on line %d +NULL +string(3) "abc" +==DONE==
\ No newline at end of file diff --git a/Zend/tests/closure_use_auto_global.phpt b/Zend/tests/closure_use_auto_global.phpt new file mode 100644 index 0000000000..9ab0897e12 --- /dev/null +++ b/Zend/tests/closure_use_auto_global.phpt @@ -0,0 +1,16 @@ +--TEST-- +Cannot use() auto-global +--FILE-- +<?php + +function test() { + $fn = function() use($GLOBALS) { + var_dump($GLOBALS); + }; + $fn(); +} +test(); + +?> +--EXPECTF-- +Fatal error: Cannot use auto-global as lexical variable in %s on line %d diff --git a/Zend/tests/closure_use_parameter_name.phpt b/Zend/tests/closure_use_parameter_name.phpt new file mode 100644 index 0000000000..7ecc6d8dd1 --- /dev/null +++ b/Zend/tests/closure_use_parameter_name.phpt @@ -0,0 +1,14 @@ +--TEST-- +Can't use name of lexical variable for parameter +--FILE-- +<?php + +$a = 1; +$fn = function ($a) use ($a) { + var_dump($a); +}; +$fn(2); + +?> +--EXPECTF-- +Fatal error: Cannot use lexical variable $a as a parameter name in %s on line %d diff --git a/Zend/tests/closure_use_variable_twice.phpt b/Zend/tests/closure_use_variable_twice.phpt new file mode 100644 index 0000000000..06c2645809 --- /dev/null +++ b/Zend/tests/closure_use_variable_twice.phpt @@ -0,0 +1,15 @@ +--TEST-- +Closure cannot use one variable twice +--FILE-- +<?php + +$a = 1; +$fn = function() use ($a, &$a) { + $a = 2; +}; +$fn(); +var_dump($a); + +?> +--EXPECTF-- +Fatal error: Cannot use variable $a twice in %s on line %d diff --git a/Zend/tests/constant_expressions_dynamic.phpt b/Zend/tests/constant_expressions_dynamic.phpt index d4e06ee258..b0ba3a5b19 100644 --- a/Zend/tests/constant_expressions_dynamic.phpt +++ b/Zend/tests/constant_expressions_dynamic.phpt @@ -42,7 +42,9 @@ var_dump( ); ?> ---EXPECT-- +--EXPECTF-- + +Warning: A non-numeric value encountered in %s on line %d int(3) string(4) "1foo" bool(false) diff --git a/Zend/tests/empty_str_offset.phpt b/Zend/tests/empty_str_offset.phpt index 486c052dc4..49e175dd21 100644 --- a/Zend/tests/empty_str_offset.phpt +++ b/Zend/tests/empty_str_offset.phpt @@ -8,6 +8,8 @@ print "- empty ---\n"; $str = "test0123"; var_dump(empty($str[-1])); +var_dump(empty($str[-10])); +var_dump(empty($str[-4])); // 0 var_dump(empty($str[0])); var_dump(empty($str[1])); var_dump(empty($str[4])); // 0 @@ -17,6 +19,8 @@ var_dump(empty($str[10000])); // non-numeric offsets print "- string ---\n"; var_dump(empty($str['-1'])); +var_dump(empty($str['-10'])); +var_dump(empty($str['-4'])); // 0 var_dump(empty($str['0'])); var_dump(empty($str['1'])); var_dump(empty($str['4'])); // 0 @@ -31,6 +35,8 @@ print "- null ---\n"; var_dump(empty($str[null])); print "- double ---\n"; var_dump(empty($str[-1.1])); +var_dump(empty($str[-10.5])); +var_dump(empty($str[-4.1])); var_dump(empty($str[-0.8])); var_dump(empty($str[-0.1])); var_dump(empty($str[0.2])); @@ -50,6 +56,8 @@ print "done\n"; ?> --EXPECTF-- - empty --- +bool(false) +bool(true) bool(true) bool(false) bool(false) @@ -58,6 +66,8 @@ bool(false) bool(true) bool(true) - string --- +bool(false) +bool(true) bool(true) bool(false) bool(false) @@ -72,6 +82,8 @@ bool(true) - null --- bool(false) - double --- +bool(false) +bool(true) bool(true) bool(false) bool(false) diff --git a/Zend/tests/foreach_list_keyed.phpt b/Zend/tests/foreach_list_keyed.phpt new file mode 100644 index 0000000000..f5fab4e342 --- /dev/null +++ b/Zend/tests/foreach_list_keyed.phpt @@ -0,0 +1,36 @@ +--TEST-- +foreach with list syntax, keyed +--FILE-- +<?php + +$points = [ + ["x" => 1, "y" => 2], + ["x" => 2, "y" => 1] +]; + +foreach ($points as list("x" => $x, "y" => $y)) { + var_dump($x, $y); +} + +echo PHP_EOL; + +$invertedPoints = [ + "x" => [1, 2], + "y" => [2, 1] +]; + +foreach ($invertedPoints as list(0 => $row1, 1 => $row2)) { + var_dump($row1, $row2); +} + +?> +--EXPECT-- +int(1) +int(2) +int(2) +int(1) + +int(1) +int(2) +int(2) +int(1) diff --git a/Zend/tests/func_get_args.phpt b/Zend/tests/func_get_args.phpt new file mode 100644 index 0000000000..eea8ae4354 --- /dev/null +++ b/Zend/tests/func_get_args.phpt @@ -0,0 +1,10 @@ +--TEST-- +Testing func_get_args() +--FILE-- +<?php + +func_get_args(); + +?> +--EXPECTF-- +Warning: func_get_args(): Called from the global scope - no function context in %s on line 3 diff --git a/Zend/tests/global_with_side_effect_name.phpt b/Zend/tests/global_with_side_effect_name.phpt new file mode 100644 index 0000000000..a1ee240c48 --- /dev/null +++ b/Zend/tests/global_with_side_effect_name.phpt @@ -0,0 +1,22 @@ +--TEST-- +Global variable import using a name with side effects +--FILE-- +<?php + +function sf($arg) { + echo "called\n"; + return $arg; +} + +function test() { + global ${sf("a")}; + var_dump($a); +} + +$a = 42; +test(); + +?> +--EXPECT-- +called +int(42) diff --git a/Zend/tests/int_conversion_exponents.phpt b/Zend/tests/int_conversion_exponents.phpt new file mode 100644 index 0000000000..d924cb7b81 --- /dev/null +++ b/Zend/tests/int_conversion_exponents.phpt @@ -0,0 +1,52 @@ +--TEST-- +Integer conversion from scientific notation +--FILE-- +<?php + +var_dump((int)"1.2345e9"); +var_dump((int)"-1.2345e9"); +var_dump(intval("1.2345e9")); +var_dump(intval("-1.2345e9")); +var_dump("1.2345e9" % PHP_INT_MAX); +var_dump("-1.2345e9" % PHP_INT_MIN); +var_dump("1.2345e9" | 0); +var_dump("-1.2345e9" | 0); + +echo PHP_EOL; + +var_dump((int)" 1.2345e9 abc"); +var_dump((int)" -1.2345e9 abc"); +var_dump(intval(" 1.2345e9 abc")); +var_dump(intval(" -1.2345e9 abc")); +var_dump(" 1.2345e9 abc" % PHP_INT_MAX); +var_dump(" -1.2345e9 abc" % PHP_INT_MIN); +var_dump(" 1.2345e9 abc" | 0); +var_dump(" -1.2345e9 abc" | 0); + +?> +--EXPECTF-- +int(1234500000) +int(-1234500000) +int(1234500000) +int(-1234500000) +int(1234500000) +int(-1234500000) +int(1234500000) +int(-1234500000) + +int(1234500000) +int(-1234500000) +int(1234500000) +int(-1234500000) + +Notice: A non well formed numeric value encountered in %s on line %d +int(1234500000) + +Notice: A non well formed numeric value encountered in %s on line %d +int(-1234500000) + +Notice: A non well formed numeric value encountered in %s on line %d +int(1234500000) + +Notice: A non well formed numeric value encountered in %s on line %d +int(-1234500000) diff --git a/Zend/tests/isset_str_offset.phpt b/Zend/tests/isset_str_offset.phpt index 7a9164a381..d693f80a52 100644 --- a/Zend/tests/isset_str_offset.phpt +++ b/Zend/tests/isset_str_offset.phpt @@ -8,6 +8,7 @@ print "- isset ---\n"; $str = "test0123"; var_dump(isset($str[-1])); +var_dump(isset($str[-10])); var_dump(isset($str[0])); var_dump(isset($str[1])); var_dump(isset($str[4])); // 0 @@ -17,6 +18,7 @@ var_dump(isset($str[10000])); // non-numeric offsets print "- string ---\n"; var_dump(isset($str['-1'])); +var_dump(isset($str['-10'])); var_dump(isset($str['0'])); var_dump(isset($str['1'])); var_dump(isset($str['4'])); // 0 @@ -31,6 +33,7 @@ print "- null ---\n"; var_dump(isset($str[null])); print "- double ---\n"; var_dump(isset($str[-1.1])); +var_dump(isset($str[-10.5])); var_dump(isset($str[-0.8])); var_dump(isset($str[-0.1])); var_dump(isset($str[0.2])); @@ -50,6 +53,7 @@ print "done\n"; ?> --EXPECTF-- - isset --- +bool(true) bool(false) bool(true) bool(true) @@ -58,6 +62,7 @@ bool(true) bool(false) bool(false) - string --- +bool(true) bool(false) bool(true) bool(true) @@ -72,6 +77,7 @@ bool(false) - null --- bool(true) - double --- +bool(true) bool(false) bool(true) bool(true) diff --git a/Zend/tests/jump16.phpt b/Zend/tests/jump16.phpt new file mode 100644 index 0000000000..cc820c4a6c --- /dev/null +++ b/Zend/tests/jump16.phpt @@ -0,0 +1,27 @@ +--TEST-- +jump 16: goto into try/catch +--FILE-- +<?php +goto a; +try { + echo "1"; +a: + echo "2"; + throw new Exception(); +} catch (Exception $e) { + echo "3"; +} +echo "4"; +goto b; +try { + echo "5"; + throw new Exception(); +} catch (Exception $e) { + echo "6"; +b: + echo "7"; +} +echo "8\n"; +?> +--EXPECT-- +23478 diff --git a/Zend/tests/jump17.phpt b/Zend/tests/jump17.phpt new file mode 100644 index 0000000000..92d3be511b --- /dev/null +++ b/Zend/tests/jump17.phpt @@ -0,0 +1,22 @@ +--TEST-- +jump 17: goto into try/catch with finally +--FILE-- +<?php +goto b; +try { + echo "1"; +a: + echo "2"; + throw new Exception(); +} catch (Exception $e) { + echo "3"; +b: + echo "4"; +} finally { + echo "5"; +c: + echo "6"; +} +echo "7\n"; +--EXPECT-- +4567 diff --git a/Zend/tests/list_keyed.phpt b/Zend/tests/list_keyed.phpt new file mode 100644 index 0000000000..b549ed9bf5 --- /dev/null +++ b/Zend/tests/list_keyed.phpt @@ -0,0 +1,71 @@ +--TEST-- +list() with keys +--FILE-- +<?php + +$antonyms = [ + "good" => "bad", + "happy" => "sad", +]; + +list("good" => $good_antonym, "happy" => $happy_antonym) = $antonyms; +var_dump($good_antonym, $happy_antonym); + +echo PHP_EOL; + +$powersOfTwo = [ + 1 => 2, + 2 => 4, + 3 => 8 +]; + +list(1 => $two_1, 2 => $two_2, 3 => $two_3) = $powersOfTwo; +var_dump($two_1, $two_2, $two_3); + +echo PHP_EOL; + +$contrivedMixedKeyTypesExample = [ + 7 => "the best PHP version", + "elePHPant" => "the cutest mascot" +]; + +list(7 => $seven, "elePHPant" => $elePHPant) = $contrivedMixedKeyTypesExample; +var_dump($seven, $elePHPant); + +echo PHP_EOL; + +$allTogetherNow = [ + "antonyms" => $antonyms, + "powersOfTwo" => $powersOfTwo, + "contrivedMixedKeyTypesExample" => $contrivedMixedKeyTypesExample +]; + +list( + "antonyms" => list("good" => $good_antonym, "happy" => $happy_antonym), + "powersOfTwo" => list(1 => $two_1, 2 => $two_2, 3 => $two_3), + "contrivedMixedKeyTypesExample" => list(7 => $seven, "elePHPant" => $elePHPant) +) = $allTogetherNow; + +var_dump($good_antonym, $happy_antonym); +var_dump($two_1, $two_2, $two_3); +var_dump($seven, $elePHPant); + +?> +--EXPECT-- +string(3) "bad" +string(3) "sad" + +int(2) +int(4) +int(8) + +string(20) "the best PHP version" +string(17) "the cutest mascot" + +string(3) "bad" +string(3) "sad" +int(2) +int(4) +int(8) +string(20) "the best PHP version" +string(17) "the cutest mascot" diff --git a/Zend/tests/list_keyed_ArrayAccess.phpt b/Zend/tests/list_keyed_ArrayAccess.phpt new file mode 100644 index 0000000000..1bb2013036 --- /dev/null +++ b/Zend/tests/list_keyed_ArrayAccess.phpt @@ -0,0 +1,54 @@ +--TEST-- +list() with keys and ArrayAccess +--FILE-- +<?php + +$antonymObject = new ArrayObject; +$antonymObject["good"] = "bad"; +$antonymObject["happy"] = "sad"; + +list("good" => $good, "happy" => $happy) = $antonymObject; +var_dump($good, $happy); + +echo PHP_EOL; + +$stdClassCollection = new SplObjectStorage; +$foo = new StdClass; +$stdClassCollection[$foo] = "foo"; +$bar = new StdClass; +$stdClassCollection[$bar] = "bar"; + +list($foo => $fooStr, $bar => $barStr) = $stdClassCollection; +var_dump($fooStr, $barStr); + +echo PHP_EOL; + +class IndexPrinter implements ArrayAccess +{ + public function offsetGet($offset) { + echo "GET "; + var_dump($offset); + } + public function offsetSet($offset, $value) { + } + public function offsetExists($offset) { + } + public function offsetUnset($offset) { + } +} + +$op = new IndexPrinter; +list(123 => $x) = $op; +// PHP shouldn't convert this to an integer offset, because it's ArrayAccess +list("123" => $x) = $op; + +?> +--EXPECT-- +string(3) "bad" +string(3) "sad" + +string(3) "foo" +string(3) "bar" + +GET int(123) +GET string(3) "123" diff --git a/Zend/tests/list_keyed_conversions.phpt b/Zend/tests/list_keyed_conversions.phpt new file mode 100644 index 0000000000..e2cf91a27d --- /dev/null +++ b/Zend/tests/list_keyed_conversions.phpt @@ -0,0 +1,32 @@ +--TEST-- +list() with non-integer-or-string keys +--FILE-- +<?php + +$results = [ + 0 => 0, + 1 => 1, + "" => "" +]; + +list(NULL => $NULL, 1.5 => $float, FALSE => $FALSE, TRUE => $TRUE) = $results; +var_dump($NULL, $float, $FALSE, $TRUE); + +echo PHP_EOL; + +list("0" => $zeroString, "1" => $oneString) = $results; +var_dump($zeroString, $oneString); + +list(STDIN => $resource) = []; + +?> +--EXPECTF-- +string(0) "" +int(1) +int(0) +int(1) + +int(0) +int(1) + +Notice: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d diff --git a/Zend/tests/list_keyed_evaluation_order.inc b/Zend/tests/list_keyed_evaluation_order.inc new file mode 100644 index 0000000000..490a6d84fe --- /dev/null +++ b/Zend/tests/list_keyed_evaluation_order.inc @@ -0,0 +1,60 @@ +<?php declare(strict_types=1); + +// Observer objects for the Zend/tests/list_keyed_evaluation_order.* tests + +class Stringable +{ + private $name; + public function __construct(string $name) { + $this->name = $name; + } + + public function __toString(): string { + echo "$this->name evaluated.", PHP_EOL; + return $this->name; + } +} + +class Indexable implements ArrayAccess +{ + private $array; + public function __construct(array $array) { + $this->array = $array; + } + + public function offsetExists($offset): bool { + echo "Existence of offset $offset checked for.", PHP_EOL; + return isset($this->array[$offset]); + } + + public function offsetUnset($offset): void { + unset($this->array[$offset]); + echo "Offset $offset removed.", PHP_EOL; + } + + public function offsetGet($offset) { + echo "Offset $offset retrieved.", PHP_EOL; + return $this->array[$offset]; + } + + public function offsetSet($offset, $value): void { + $this->array[$offset] = $value; + echo "Offset $offset set to $value.", PHP_EOL; + } +} + +class IndexableRetrievable +{ + private $label; + private $indexable; + + public function __construct(string $label, Indexable $indexable) { + $this->label = $label; + $this->indexable = $indexable; + } + + public function getIndexable(): Indexable { + echo "Indexable $this->label retrieved.", PHP_EOL; + return $this->indexable; + } +} diff --git a/Zend/tests/list_keyed_evaluation_order.phpt b/Zend/tests/list_keyed_evaluation_order.phpt new file mode 100644 index 0000000000..0f0652b6a9 --- /dev/null +++ b/Zend/tests/list_keyed_evaluation_order.phpt @@ -0,0 +1,35 @@ +--TEST-- +list() with keys, evaluation order +--FILE-- +<?php + +require_once "list_keyed_evaluation_order.inc"; + +$a = new Stringable("A"); +$c = new Stringable("C"); + +$e = new IndexableRetrievable("E", new Indexable(["A" => "value for offset A", "C" => "value for offset C"])); + +$store = new Indexable([]); + +// list($a => $b, $c => $d) = $e; +// Should be evaluated in the order: +// 1. Evaluate $e +// 2. Evaluate $a +// 3. Evaluate $e[$a] +// 4. Assign $b from $e[$a] +// 5. Evaluate $c +// 6. Evaluate $e[$c] +// 7. Assign $c from $e[$a] + +list((string)$a => $store["B"], (string)$c => $store["D"]) = $e->getIndexable(); + +?> +--EXPECT-- +Indexable E retrieved. +A evaluated. +Offset A retrieved. +Offset B set to value for offset A. +C evaluated. +Offset C retrieved. +Offset D set to value for offset C. diff --git a/Zend/tests/list_keyed_evaluation_order_2.phpt b/Zend/tests/list_keyed_evaluation_order_2.phpt new file mode 100644 index 0000000000..ddfba68c46 --- /dev/null +++ b/Zend/tests/list_keyed_evaluation_order_2.phpt @@ -0,0 +1,77 @@ +--TEST-- +list() with keys, evaluation order #2 +--FILE-- +<?php + +// All the following should print 'a' then 'b' + +list($a, $b) = ['a', 'b']; +var_dump($a); +var_dump($b); + +list(0 => $a, 1 => $b) = ['a', 'b']; +var_dump($a); +var_dump($b); + +list(1 => $b, 0 => $a) = ['a', 'b']; +var_dump($a); +var_dump($b); + +$arr = []; +list($arr[], $arr[]) = ['a', 'b']; +var_dump($arr[0]); +var_dump($arr[1]); + +$arr = []; +list(0 => $arr[], 1 => $arr[]) = ['a', 'b']; +var_dump($arr[0]); +var_dump($arr[1]); + +$arr = []; +list(1 => $arr[], 0 => $arr[]) = ['b', 'a']; +var_dump($arr[0]); +var_dump($arr[1]); + +$arr = []; +list(list(1 => $arr[], 0 => $arr[])) = [['b', 'a']]; +var_dump($arr[0]); +var_dump($arr[1]); + +$arr = []; +list('key1' => $arr[], 'key2' => $arr[]) = ['key2' => 'b', 'key1' => 'a']; +var_dump($arr[0]); +var_dump($arr[1]); + +// This should print 'foo' +$a = 0; +list($a => $a) = ['foo', 'bar']; +var_dump($a); + +// This should print 'bar' then 'foo' +$a = 0; +$b = 1; +list($b => $a, $a => $c) = ['bar' => 'foo', 1 => 'bar']; +var_dump($a); +var_dump($c); + +?> +--EXPECT-- +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(1) "a" +string(1) "b" +string(3) "foo" +string(3) "bar" +string(3) "foo" diff --git a/Zend/tests/list_keyed_evaluation_order_3.phpt b/Zend/tests/list_keyed_evaluation_order_3.phpt new file mode 100644 index 0000000000..7850834c3b --- /dev/null +++ b/Zend/tests/list_keyed_evaluation_order_3.phpt @@ -0,0 +1,24 @@ +--TEST-- +list() with keys, evaluation order #3 +--FILE-- +<?php + +$i = 0; +$a = [ + 0 => [ + 'b' => 'bar', + 'a' => 'foo', + ], + 1 => 'a', + 3 => 'b', +]; +list($a[$i++] => $a[$i++], $a[$i++] => $a[$i++]) = $a[$i++]; +var_dump($i); // should be 5 +var_dump($a[2]); // should be 'foo' +var_dump($a[4]); // should be 'bar' + +?> +--EXPECT-- +int(5) +string(3) "foo" +string(3) "bar" diff --git a/Zend/tests/list_keyed_evaluation_order_nested.phpt b/Zend/tests/list_keyed_evaluation_order_nested.phpt new file mode 100644 index 0000000000..8a7725d4ea --- /dev/null +++ b/Zend/tests/list_keyed_evaluation_order_nested.phpt @@ -0,0 +1,77 @@ +--TEST-- +list() with keys, evaluation order: nested +--FILE-- +<?php + +require_once "list_keyed_evaluation_order.inc"; + +$a = new Stringable("A"); +$c = new Stringable("C"); +$f = new Stringable("F"); +$g = new Stringable("G"); +$i = new Stringable("I"); + +$k = new IndexableRetrievable("K", new Indexable([ + "A" => "offset value for A", + "C" => new Indexable([ + 0 => "offset value for 0", + 1 => "offset value for 1" + ]), + "F" => new Indexable([ + "G" => "offset value for G", + "I" => "offset value for I" + ]) +])); + +$store = new Indexable([]); + +// list($a => $b, $c => list($d, $e), $f => list($g => $h, $i => $j)) = $k; +// Should be evaluated in the order: +// 1. Evaluate $k +// 2. Evaluate $a +// 3. Evaluate $k[$a] +// 4. Assign $b from $k[$a] +// 5. Evaluate $c +// 6. Evaluate $k[$c] +// 7. Evaluate $k[$c][0] +// 8. Assign $d from $k[$c][0] +// 9. Evaluate $k[$c][1] +// 10. Assign $e from $k[$c][1] +// 11. Evaluate $f +// 12. Evaluate $k[$f] +// 13. Evaluate $g +// 14. Evaluate $k[$f][$g] +// 15. Assign $h from $k[$f][$g] +// 16. Evaluate $i +// 17. Evaluate $k[$f][$i] +// 18. Assign $j from $k[$f][$i] + +list( + (string)$a => $store["B"], + (string)$c => list($store["D"], $store["E"]), + (string)$f => list( + (string)$g => $store["H"], + (string)$i => $store["J"] + ) +) = $k->getIndexable(); + +?> +--EXPECT-- +Indexable K retrieved. +A evaluated. +Offset A retrieved. +Offset B set to offset value for A. +C evaluated. +Offset C retrieved. +Offset 0 retrieved. +Offset D set to offset value for 0. +Offset 1 retrieved. +Offset E set to offset value for 1. +F evaluated. +Offset F retrieved. +G evaluated. +Offset G retrieved. +Offset H set to offset value for G. +I evaluated. +Offset I retrieved. +Offset J set to offset value for I. diff --git a/Zend/tests/list_keyed_non_literals.phpt b/Zend/tests/list_keyed_non_literals.phpt new file mode 100644 index 0000000000..80f22eda22 --- /dev/null +++ b/Zend/tests/list_keyed_non_literals.phpt @@ -0,0 +1,30 @@ +--TEST-- +list() with constant keys +--FILE-- +<?php + +$arr = [ + 1 => "one", + 2 => "two", + 3 => "three" +]; + +const COMPILE_TIME_RESOLVABLE = 1; + +define('PROBABLY_NOT_COMPILE_TIME_RESOLVABLE', file_get_contents("data:text/plain,2")); + +$probablyNotCompileTimeResolvable3 = cos(0) * 3; + +list( + COMPILE_TIME_RESOLVABLE => $one, + PROBABLY_NOT_COMPILE_TIME_RESOLVABLE => $two, + $probablyNotCompileTimeResolvable3 => $three +) = $arr; + +var_dump($one, $two, $three); + +?> +--EXPECTF-- +string(3) "one" +string(3) "two" +string(5) "three" diff --git a/Zend/tests/list_keyed_trailing_comma.phpt b/Zend/tests/list_keyed_trailing_comma.phpt new file mode 100644 index 0000000000..e0af0aed21 --- /dev/null +++ b/Zend/tests/list_keyed_trailing_comma.phpt @@ -0,0 +1,38 @@ +--TEST-- +list() with keys and a trailing comma +--FILE-- +<?php + +$antonyms = [ + "good" => "bad", + "happy" => "sad", +]; + +list( + "good" => $good, + "happy" => $happy +) = $antonyms; + +var_dump($good, $happy); + +echo PHP_EOL; + +$antonyms = [ + "good" => "bad", + "happy" => "sad", +]; + +list( + "good" => $good, + "happy" => $happy, +) = $antonyms; + +var_dump($good, $happy); + +?> +--EXPECT-- +string(3) "bad" +string(3) "sad" + +string(3) "bad" +string(3) "sad" diff --git a/Zend/tests/list_keyed_undefined.phpt b/Zend/tests/list_keyed_undefined.phpt new file mode 100644 index 0000000000..a18e3b4d20 --- /dev/null +++ b/Zend/tests/list_keyed_undefined.phpt @@ -0,0 +1,22 @@ +--TEST-- +list() with undefined keys +--FILE-- +<?php + +$contrivedMixedKeyTypesExample = [ + 7 => "the best PHP version", + "elePHPant" => "the cutest mascot" +]; + +list(5 => $five, "duke" => $duke) = $contrivedMixedKeyTypesExample; + +var_dump($five, $duke); + +?> +--EXPECTF-- + +Notice: Undefined offset: 5 in %s on line %d + +Notice: Undefined index: duke in %s on line %d +NULL +NULL diff --git a/Zend/tests/list_mixed_keyed_unkeyed.phpt b/Zend/tests/list_mixed_keyed_unkeyed.phpt new file mode 100644 index 0000000000..5562479fc3 --- /dev/null +++ b/Zend/tests/list_mixed_keyed_unkeyed.phpt @@ -0,0 +1,16 @@ +--TEST-- +list() with both keyed and unkeyed elements +--FILE-- +<?php + +$contrivedKeyedAndUnkeyedArrayExample = [ + 0, + 1 => 1, + "foo" => "bar" +]; + +list($zero, 1 => $one, "foo" => $foo) = $contrivedKeyedAndUnkeyedArrayExample; + +?> +--EXPECTF-- +Parse error: syntax error, unexpected %s in %s on line %d diff --git a/Zend/tests/list_mixed_nested_keyed_unkeyed.phpt b/Zend/tests/list_mixed_nested_keyed_unkeyed.phpt new file mode 100644 index 0000000000..3087775b76 --- /dev/null +++ b/Zend/tests/list_mixed_nested_keyed_unkeyed.phpt @@ -0,0 +1,34 @@ +--TEST-- +list() with nested unkeyed and keyed list() +--FILE-- +<?php + +$points = [ + ["x" => 1, "y" => 2], + ["x" => 2, "y" => 1] +]; + +list(list("x" => $x1, "y" => $y1), list("x" => $x2, "y" => $y2)) = $points; +var_dump($x1, $y1, $x2, $y2); + +echo PHP_EOL; + +$invertedPoints = [ + "x" => [1, 2], + "y" => [2, 1] +]; + +list("x" => list($x1, $x2), "y" => list($y1, $y2)) = $invertedPoints; +var_dump($x1, $y1, $x2, $y2); + +?> +--EXPECT-- +int(1) +int(2) +int(2) +int(1) + +int(1) +int(2) +int(2) +int(1) diff --git a/Zend/tests/new_args_without_ctor.phpt b/Zend/tests/new_args_without_ctor.phpt new file mode 100644 index 0000000000..91456890d2 --- /dev/null +++ b/Zend/tests/new_args_without_ctor.phpt @@ -0,0 +1,10 @@ +--TEST-- +Argument of new on class without constructor are evaluated +--FILE-- +<?php + +new stdClass(print 'a', print 'b'); + +?> +--EXPECT-- +ab diff --git a/Zend/tests/numeric_string_errors.phpt b/Zend/tests/numeric_string_errors.phpt new file mode 100644 index 0000000000..e98c58dda7 --- /dev/null +++ b/Zend/tests/numeric_string_errors.phpt @@ -0,0 +1,195 @@ +--TEST-- +Invalid numeric string E_WARNINGs and E_NOTICEs +--FILE-- +<?php + +var_dump("2 Lorem" + "3 ipsum"); +var_dump("dolor" + "sit"); +echo "---", PHP_EOL; +var_dump("5 amet," - "7 consectetur"); +var_dump("adipiscing" - "elit,"); +echo "---", PHP_EOL; +var_dump("11 sed" * "13 do"); +var_dump("eiusmod" * "tempor"); +echo "---", PHP_EOL; +var_dump("17 incididunt" / "19 ut"); +var_dump("labore" / "et"); +echo "---", PHP_EOL; +var_dump("23 dolore" ** "29 magna"); +var_dump("aliqua." ** "Ut"); +echo "---", PHP_EOL; +var_dump("31 enim" % "37 ad"); +try { + var_dump("minim" % "veniam,"); +} catch (DivisionByZeroError $e) { +} +echo "---", PHP_EOL; +var_dump("41 minim" << "43 veniam,"); +var_dump("quis" << "nostrud"); +echo "---", PHP_EOL; +var_dump("47 exercitation" >> "53 ullamco"); +var_dump("laboris" >> "nisi"); +echo "---", PHP_EOL; +var_dump("59 ut" | 61); +var_dump(67 | "71 aliquip"); +var_dump("ex" | 73); +var_dump(79 | "ea"); +echo "---", PHP_EOL; +var_dump("83 commodo" & 89); +var_dump(97 & "101 consequat."); +var_dump("Duis" & 103); +var_dump(107 & "aute"); +echo "---", PHP_EOL; +var_dump("109 irure" ^ 113); +var_dump(127 ^ "131 dolor"); +var_dump("in" ^ 137); +var_dump(139 ^ "reprehenderit"); +echo "---", PHP_EOL; +var_dump(+"149 in"); +var_dump(+"voluptate"); +echo "---", PHP_EOL; +var_dump(-"151 velit"); +var_dump(-"esse"); +?> +--EXPECTF-- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +int(5) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +--- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +int(-2) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +--- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +int(143) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +--- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +float(0.89473684210526) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d + +Warning: Division by zero in %s on line %d +float(NAN) +--- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +float(3.0910586430935E+39) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(1) +--- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +int(31) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +--- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +int(%d) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +--- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +int(0) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +--- + +Notice: A non well formed numeric value encountered in %s on line %d +int(63) + +Notice: A non well formed numeric value encountered in %s on line %d +int(71) + +Warning: A non-numeric value encountered in %s on line %d +int(73) + +Warning: A non-numeric value encountered in %s on line %d +int(79) +--- + +Notice: A non well formed numeric value encountered in %s on line %d +int(81) + +Notice: A non well formed numeric value encountered in %s on line %d +int(97) + +Warning: A non-numeric value encountered in %s on line %d +int(0) + +Warning: A non-numeric value encountered in %s on line %d +int(0) +--- + +Notice: A non well formed numeric value encountered in %s on line %d +int(28) + +Notice: A non well formed numeric value encountered in %s on line %d +int(252) + +Warning: A non-numeric value encountered in %s on line %d +int(137) + +Warning: A non-numeric value encountered in %s on line %d +int(139) +--- + +Notice: A non well formed numeric value encountered in %s on line %d +int(149) + +Warning: A non-numeric value encountered in %s on line %d +int(0) +--- + +Notice: A non well formed numeric value encountered in %s on line %d +int(-151) + +Warning: A non-numeric value encountered in %s on line %d +int(0) diff --git a/Zend/tests/numeric_string_errors_assign.phpt b/Zend/tests/numeric_string_errors_assign.phpt new file mode 100644 index 0000000000..8d882aadcc --- /dev/null +++ b/Zend/tests/numeric_string_errors_assign.phpt @@ -0,0 +1,236 @@ +--TEST-- +Invalid numeric string E_WARNINGs and E_NOTICEs, combined assignment operations +--FILE-- +<?php + +// prevents CT eval +function foxcache($val) { + return [$val][0]; +} + +$a = foxcache("2 Lorem"); +$a += "3 ipsum"; +var_dump($a); +$a = foxcache("dolor"); +$a += "sit"; +var_dump($a); +echo "---", PHP_EOL; +$a = foxcache("5 amet,"); +$a -= "7 consectetur"; +var_dump($a); +$a = foxcache("adipiscing"); +$a -= "elit,"; +var_dump($a); +echo "---", PHP_EOL; +$a = foxcache("11 sed"); +$a *= "13 do"; +var_dump($a); +$a = foxcache("eiusmod"); +$a *= "tempor"; +var_dump($a); +echo "---", PHP_EOL; +$a = foxcache("17 incididunt"); +$a /= "19 ut"; +var_dump($a); +$a = foxcache("labore"); +$a /= "et"; +var_dump($a); +echo "---", PHP_EOL; +$a = foxcache("23 dolore"); +$a **= "29 magna"; +var_dump($a); +$a = foxcache("aliqua."); +$a **= "Ut"; +var_dump($a); +echo "---", PHP_EOL; +$a = foxcache("31 enim"); +$a %= "37 ad"; +var_dump($a); +try { + $a = foxcache("minim"); + $a %= "veniam,"; + var_dump($a); +} catch (DivisionByZeroError $e) { +} +echo "---", PHP_EOL; +$a = foxcache("41 minim"); +$a <<= "43 veniam,"; +var_dump($a); +$a = foxcache("quis"); +$a <<= "nostrud"; +var_dump($a); +echo "---", PHP_EOL; +$a = foxcache("47 exercitation"); +$a >>= "53 ullamco"; +var_dump($a); +$a = foxcache("laboris"); +$a >>= "nisi"; +var_dump($a); +echo "---", PHP_EOL; +$a = foxcache("59 ut"); +$a |= 61; +var_dump($a); +$a = foxcache(67); +$a |= "71 aliquip"; +var_dump($a); +$a = foxcache("ex"); +$a |= 73; +var_dump($a); +$a = foxcache(79); +$a |= "ea"; +var_dump($a); +echo "---", PHP_EOL; +$a = foxcache("83 commodo"); +$a &= 89; +var_dump($a); +$a = foxcache(97); +$a &= "101 consequat."; +var_dump($a); +$a = foxcache("Duis"); +$a &= 103; +var_dump($a); +$a = foxcache(107); +$a &= "aute"; +var_dump($a); +echo "---", PHP_EOL; +$a = foxcache("109 irure"); +$a ^= 113; +var_dump($a); +$a = foxcache(127); +$a ^= "131 dolor"; +var_dump($a); +$a = foxcache("in"); +$a ^= 137; +var_dump($a); +$a = foxcache(139); +$a ^= "reprehenderit"; +var_dump($a); +?> +--EXPECTF-- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +int(5) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +--- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +int(-2) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +--- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +int(143) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +--- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +float(0.89473684210526) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d + +Warning: Division by zero in %s on line %d +float(NAN) +--- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +float(3.0910586430935E+39) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(1) +--- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +int(31) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +--- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +int(%d) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +--- + +Notice: A non well formed numeric value encountered in %s on line %d + +Notice: A non well formed numeric value encountered in %s on line %d +int(0) + +Warning: A non-numeric value encountered in %s on line %d + +Warning: A non-numeric value encountered in %s on line %d +int(0) +--- + +Notice: A non well formed numeric value encountered in %s on line %d +int(63) + +Notice: A non well formed numeric value encountered in %s on line %d +int(71) + +Warning: A non-numeric value encountered in %s on line %d +int(73) + +Warning: A non-numeric value encountered in %s on line %d +int(79) +--- + +Notice: A non well formed numeric value encountered in %s on line %d +int(81) + +Notice: A non well formed numeric value encountered in %s on line %d +int(97) + +Warning: A non-numeric value encountered in %s on line %d +int(0) + +Warning: A non-numeric value encountered in %s on line %d +int(0) +--- + +Notice: A non well formed numeric value encountered in %s on line %d +int(28) + +Notice: A non well formed numeric value encountered in %s on line %d +int(252) + +Warning: A non-numeric value encountered in %s on line %d +int(137) + +Warning: A non-numeric value encountered in %s on line %d +int(139) diff --git a/Zend/tests/overloaded_func_001.phpt b/Zend/tests/overloaded_func_001.phpt new file mode 100644 index 0000000000..2702772a46 --- /dev/null +++ b/Zend/tests/overloaded_func_001.phpt @@ -0,0 +1,15 @@ +--TEST-- +Overloaded function 001 +--SKIPIF-- +<?php +if (!PHP_DEBUG) die("skip only run in debug version"); +?> +--FILE-- +<?php +var_dump(_ZendTestClass::test()); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Cannot call overloaded function for non-object in %soverloaded_func_001.php:%d +Stack trace: +#0 {main} + thrown in %soverloaded_func_001.php on line %d diff --git a/Zend/tests/overloaded_func_002.phpt b/Zend/tests/overloaded_func_002.phpt new file mode 100644 index 0000000000..6c16965919 --- /dev/null +++ b/Zend/tests/overloaded_func_002.phpt @@ -0,0 +1,13 @@ +--TEST-- +Overloaded function 002 +--SKIPIF-- +<?php +if (!PHP_DEBUG) die("skip only run in debug version"); +?> +--FILE-- +<?php +$a = new _ZendTestClass(); +var_dump($a->{trim(" test")}()); +?> +--EXPECT-- +string(4) "test" diff --git a/Zend/tests/return_types/void_allowed.phpt b/Zend/tests/return_types/void_allowed.phpt new file mode 100644 index 0000000000..8f07c7392e --- /dev/null +++ b/Zend/tests/return_types/void_allowed.phpt @@ -0,0 +1,20 @@ +--TEST-- +void return type: acceptable cases +--FILE-- +<?php + +function foo(): void { + // okay +} + +foo(); + +function bar(): void { + return; // okay +} + +bar(); + +echo "OK!", PHP_EOL; +--EXPECT-- +OK! diff --git a/Zend/tests/return_types/void_disallowed1.phpt b/Zend/tests/return_types/void_disallowed1.phpt new file mode 100644 index 0000000000..b20f129a58 --- /dev/null +++ b/Zend/tests/return_types/void_disallowed1.phpt @@ -0,0 +1,12 @@ +--TEST-- +void return type: unacceptable cases: explicit NULL return +--FILE-- +<?php + +function foo(): void { + return NULL; // not permitted in a void function +} + +// Note the lack of function call: function validated at compile-time +--EXPECTF-- +Fatal error: A void function must not return a value in %s on line %d diff --git a/Zend/tests/return_types/void_disallowed2.phpt b/Zend/tests/return_types/void_disallowed2.phpt new file mode 100644 index 0000000000..7bbc3ac24f --- /dev/null +++ b/Zend/tests/return_types/void_disallowed2.phpt @@ -0,0 +1,12 @@ +--TEST-- +void return type: unacceptable cases: explicit return of some other value +--FILE-- +<?php + +function foo(): void { + return -1; // not permitted in a void function +} + +// Note the lack of function call: function validated at compile-time +--EXPECTF-- +Fatal error: A void function must not return a value in %s on line %d diff --git a/Zend/tests/return_types/void_parameter.phpt b/Zend/tests/return_types/void_parameter.phpt new file mode 100644 index 0000000000..4c6e918406 --- /dev/null +++ b/Zend/tests/return_types/void_parameter.phpt @@ -0,0 +1,8 @@ +--TEST-- +void return type: not valid as a parameter type +--FILE-- +<?php + +function foobar(void $a) {} +--EXPECTF-- +Fatal error: void cannot be used as a parameter type in %s on line %d diff --git a/Zend/tests/self_and.phpt b/Zend/tests/self_and.phpt index cdcde77992..44db877e92 100644 --- a/Zend/tests/self_and.phpt +++ b/Zend/tests/self_and.phpt @@ -20,6 +20,10 @@ echo "Done\n"; ?> --EXPECTF-- int(18) + +Warning: A non-numeric value encountered in %s on line %d int(0) + +Notice: A non well formed numeric value encountered in %s on line %d int(33) Done diff --git a/Zend/tests/self_instanceof_outside_class.phpt b/Zend/tests/self_instanceof_outside_class.phpt new file mode 100644 index 0000000000..4caef37883 --- /dev/null +++ b/Zend/tests/self_instanceof_outside_class.phpt @@ -0,0 +1,17 @@ +--TEST-- +instanceof self outside a class +--FILE-- +<?php + +$fn = function() { + try { + new stdClass instanceof self; + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } +}; +$fn(); + +?> +--EXPECT-- +Cannot access self:: when no class scope is active diff --git a/Zend/tests/self_method_or_prop_outside_class.phpt b/Zend/tests/self_method_or_prop_outside_class.phpt new file mode 100644 index 0000000000..e4a499def8 --- /dev/null +++ b/Zend/tests/self_method_or_prop_outside_class.phpt @@ -0,0 +1,36 @@ +--TEST-- +Accessing self:: properties or methods outside a class +--FILE-- +<?php + +$fn = function() { + $str = "foo"; + try { + self::${$str . "bar"}; + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + try { + unset(self::${$str . "bar"}); + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + try { + isset(self::${$str . "bar"}); + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + try { + self::{$str . "bar"}(); + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } +}; +$fn(); + +?> +--EXPECT-- +Cannot access self:: when no class scope is active +Cannot access self:: when no class scope is active +Cannot access self:: when no class scope is active +Cannot access self:: when no class scope is active diff --git a/Zend/tests/self_mod.phpt b/Zend/tests/self_mod.phpt index 19e45d88fc..0b10987aeb 100644 --- a/Zend/tests/self_mod.phpt +++ b/Zend/tests/self_mod.phpt @@ -20,6 +20,10 @@ echo "Done\n"; ?> --EXPECTF-- int(13) + +Warning: A non-numeric value encountered in %s on line %d int(0) + +Notice: A non well formed numeric value encountered in %s on line %d int(3) Done diff --git a/Zend/tests/self_or.phpt b/Zend/tests/self_or.phpt index ae667bff16..8ace518bde 100644 --- a/Zend/tests/self_or.phpt +++ b/Zend/tests/self_or.phpt @@ -20,6 +20,10 @@ echo "Done\n"; ?> --EXPECTF-- int(127) + +Warning: A non-numeric value encountered in %s on line %d int(11) + +Notice: A non well formed numeric value encountered in %s on line %d int(45345) Done diff --git a/Zend/tests/self_xor.phpt b/Zend/tests/self_xor.phpt index a7e43f539d..c097930d6d 100644 --- a/Zend/tests/self_xor.phpt +++ b/Zend/tests/self_xor.phpt @@ -20,6 +20,10 @@ echo "Done\n"; ?> --EXPECTF-- int(109) + +Warning: A non-numeric value encountered in %s on line %d int(11) + +Notice: A non well formed numeric value encountered in %s on line %d int(45312) Done diff --git a/Zend/tests/shift_001.phpt b/Zend/tests/shift_001.phpt index aeb399452d..7546f1a6d8 100644 --- a/Zend/tests/shift_001.phpt +++ b/Zend/tests/shift_001.phpt @@ -20,6 +20,10 @@ echo "Done\n"; ?> --EXPECTF-- int(492) + +Warning: A non-numeric value encountered in %s on line %d int(0) + +Notice: A non well formed numeric value encountered in %s on line %d int(362760) Done diff --git a/Zend/tests/shift_002.phpt b/Zend/tests/shift_002.phpt index 4d8421a566..6288152585 100644 --- a/Zend/tests/shift_002.phpt +++ b/Zend/tests/shift_002.phpt @@ -20,6 +20,10 @@ echo "Done\n"; ?> --EXPECTF-- int(30) + +Warning: A non-numeric value encountered in %s on line %d int(0) + +Notice: A non well formed numeric value encountered in %s on line %d int(5668) Done diff --git a/Zend/tests/str_offset_001.phpt b/Zend/tests/str_offset_001.phpt index 8a6b91b49a..3317674857 100644 --- a/Zend/tests/str_offset_001.phpt +++ b/Zend/tests/str_offset_001.phpt @@ -1,51 +1,46 @@ ---TEST--
-string offset 001
---FILE--
-<?php
-function foo($x) {
- var_dump($x);
-}
-
-$str = "abc";
-var_dump($str[-1]);
-var_dump($str[0]);
-var_dump($str[1]);
-var_dump($str[2]);
-var_dump($str[3]);
-var_dump($str[1][0]);
-var_dump($str[2][1]);
-
-foo($str[-1]);
-foo($str[0]);
-foo($str[1]);
-foo($str[2]);
-foo($str[3]);
-foo($str[1][0]);
-foo($str[2][1]);
-?>
---EXPECTF--
-Notice: Uninitialized string offset: -1 in %sstr_offset_001.php on line %d
-string(0) ""
-string(1) "a"
-string(1) "b"
-string(1) "c"
-
-Notice: Uninitialized string offset: 3 in %sstr_offset_001.php on line %d
-string(0) ""
-string(1) "b"
-
-Notice: Uninitialized string offset: 1 in %sstr_offset_001.php on line %d
-string(0) ""
-
-Notice: Uninitialized string offset: -1 in %sstr_offset_001.php on line %d
-string(0) ""
-string(1) "a"
-string(1) "b"
-string(1) "c"
-
-Notice: Uninitialized string offset: 3 in %sstr_offset_001.php on line %d
-string(0) ""
-string(1) "b"
-
-Notice: Uninitialized string offset: 1 in %sstr_offset_001.php on line %d
-string(0) ""
+--TEST-- +string offset 001 +--FILE-- +<?php +// Test positive or null string offsets + +function foo($x) { + var_dump($x); +} + +$str = "abc"; +var_dump($str[0]); +var_dump($str[1]); +var_dump($str[2]); +var_dump($str[3]); +var_dump($str[1][0]); +var_dump($str[2][1]); + +foo($str[0]); +foo($str[1]); +foo($str[2]); +foo($str[3]); +foo($str[1][0]); +foo($str[2][1]); +?> +--EXPECTF-- +string(1) "a" +string(1) "b" +string(1) "c" + +Notice: Uninitialized string offset: 3 in %sstr_offset_001.php on line %d +string(0) "" +string(1) "b" + +Notice: Uninitialized string offset: 1 in %sstr_offset_001.php on line %d +string(0) "" +string(1) "a" +string(1) "b" +string(1) "c" + +Notice: Uninitialized string offset: 3 in %sstr_offset_001.php on line %d +string(0) "" +string(1) "b" + +Notice: Uninitialized string offset: 1 in %sstr_offset_001.php on line %d +string(0) "" diff --git a/Zend/tests/str_offset_003.phpt b/Zend/tests/str_offset_003.phpt new file mode 100644 index 0000000000..e357ac0c01 --- /dev/null +++ b/Zend/tests/str_offset_003.phpt @@ -0,0 +1,37 @@ +--TEST-- +string offset 003 +--FILE-- +<?php +// Test negative string offsets + +function foo($x) { + var_dump($x); +} + +$str = "abcdef"; +var_dump($str[-10]); +var_dump($str[-3]); +var_dump($str[2][-2]); +var_dump($str[2][-1]); + +foo($str[-10]); +foo($str[-3]); +foo($str[2][-2]); +foo($str[2][-1]); +?> +--EXPECTF-- +Notice: Uninitialized string offset: -10 in %sstr_offset_003.php on line %d +string(0) "" +string(1) "d" + +Notice: Uninitialized string offset: -2 in %sstr_offset_003.php on line %d +string(0) "" +string(1) "c" + +Notice: Uninitialized string offset: -10 in %sstr_offset_003.php on line %d +string(0) "" +string(1) "d" + +Notice: Uninitialized string offset: -2 in %sstr_offset_003.php on line %d +string(0) "" +string(1) "c" diff --git a/Zend/tests/str_offset_004.phpt b/Zend/tests/str_offset_004.phpt new file mode 100644 index 0000000000..c8ce607535 --- /dev/null +++ b/Zend/tests/str_offset_004.phpt @@ -0,0 +1,49 @@ +--TEST-- +string offset 004 +--FILE-- +<?php +// Test assignments using (positive and negative) string offsets + +$str = "abcdefghijklmno"; +$i = 3; +$j = -4; + +$str{2} = 'C'; +var_dump($str); + +$str{$i} = 'Z'; +var_dump($str); + +$str{-5} = 'P'; +var_dump($str); + +$str{$j} = 'Q'; +var_dump($str); + +$str{-20} = 'Y'; +var_dump($str); + +$str{-strlen($str)} = strtoupper($str{0}); /* An exotic ucfirst() ;) */ +var_dump($str); + +$str{20} = 'N'; +var_dump($str); + +$str{-2} = 'UFO'; +var_dump($str); + +$str{-$i} = $str{$j*2}; +var_dump($str); +?> +--EXPECTF-- +string(15) "abCdefghijklmno" +string(15) "abCZefghijklmno" +string(15) "abCZefghijPlmno" +string(15) "abCZefghijPQmno" + +Warning: Illegal string offset: -20 in %sstr_offset_004.php on line %d +string(15) "abCZefghijPQmno" +string(15) "AbCZefghijPQmno" +string(21) "AbCZefghijPQmno N" +string(21) "AbCZefghijPQmno UN" +string(21) "AbCZefghijPQmno nUN" diff --git a/Zend/tests/temporary_cleaning_001.phpt b/Zend/tests/temporary_cleaning_001.phpt index 40340bc3da..f2ccbb35b8 100644 --- a/Zend/tests/temporary_cleaning_001.phpt +++ b/Zend/tests/temporary_cleaning_001.phpt @@ -1,7 +1,5 @@ --TEST-- Temporary leak on exception ---XFAIL-- -See Bug #62210 and attempt to fix it in "tmp_livelibess" branch --FILE-- <?php diff --git a/Zend/tests/temporary_cleaning_003.phpt b/Zend/tests/temporary_cleaning_003.phpt index 0f7d9450eb..acff8c85f0 100644 --- a/Zend/tests/temporary_cleaning_003.phpt +++ b/Zend/tests/temporary_cleaning_003.phpt @@ -1,7 +1,5 @@ --TEST-- Fundamental memory leak test on temporaries ---XFAIL-- -See Bug #62210 and attempt to fix it in "tmp_livelibess" branch --FILE-- <?php diff --git a/Zend/tests/temporary_cleaning_004.phpt b/Zend/tests/temporary_cleaning_004.phpt index e2b093654f..b8a02516b0 100644 --- a/Zend/tests/temporary_cleaning_004.phpt +++ b/Zend/tests/temporary_cleaning_004.phpt @@ -1,7 +1,5 @@ --TEST-- Temporary leak with switch ---XFAIL-- -See Bug #62210 and attempt to fix it in "tmp_livelibess" branch --FILE-- <?php diff --git a/Zend/tests/temporary_cleaning_005.phpt b/Zend/tests/temporary_cleaning_005.phpt index f671c32543..e8c7febe0b 100644 --- a/Zend/tests/temporary_cleaning_005.phpt +++ b/Zend/tests/temporary_cleaning_005.phpt @@ -1,7 +1,5 @@ --TEST-- Temporary leak with foreach ---XFAIL-- -See Bug #62210 and attempt to fix it in "tmp_livelibess" branch --FILE-- <?php diff --git a/Zend/tests/temporary_cleaning_006.phpt b/Zend/tests/temporary_cleaning_006.phpt index 435e7b12dd..a7936d3915 100644 --- a/Zend/tests/temporary_cleaning_006.phpt +++ b/Zend/tests/temporary_cleaning_006.phpt @@ -1,7 +1,5 @@ --TEST-- Exception after separation during indirect write to fcall result ---XFAIL-- -See Bug #62210 and attempt to fix it in "tmp_livelibess" branch --FILE-- <?php diff --git a/Zend/tests/temporary_cleaning_008.phpt b/Zend/tests/temporary_cleaning_008.phpt new file mode 100644 index 0000000000..fabd3b4b38 --- /dev/null +++ b/Zend/tests/temporary_cleaning_008.phpt @@ -0,0 +1,15 @@ +--TEST-- +Optimization of constant switch expression +--FILE-- +<?php +try { + switch ("1" . (int)2) { + case 12: + throw new Exception(); + } +} catch (Exception $e) { + echo "exception\n"; +} +?> +--EXPECT-- +exception diff --git a/Zend/tests/temporary_cleaning_009.phpt b/Zend/tests/temporary_cleaning_009.phpt new file mode 100644 index 0000000000..32a84a6ffd --- /dev/null +++ b/Zend/tests/temporary_cleaning_009.phpt @@ -0,0 +1,27 @@ +--TEST-- +Live range & free on return +--FILE-- +<?php +class bar { + public $foo = 1; + public $bar = 1; + + function __destruct() { + throw $this->foo; + } +} +foreach (new bar as &$foo) { + try { + $foo = new Exception; + return; // frees the loop variable + } catch (Exception $e) { + echo "exception\n"; + } +} +echo "end\n"; +?> +--EXPECTF-- +Fatal error: Uncaught Exception in %stemporary_cleaning_009.php:12 +Stack trace: +#0 {main} + thrown in %stemporary_cleaning_009.php on line 12 diff --git a/Zend/tests/temporary_cleaning_010.phpt b/Zend/tests/temporary_cleaning_010.phpt new file mode 100644 index 0000000000..96eab121b8 --- /dev/null +++ b/Zend/tests/temporary_cleaning_010.phpt @@ -0,0 +1,23 @@ +--TEST-- +Live range & throw from finally +--XFAIL-- +See Bug #62210 and attempt to fix it in "tmp_livelibess" branch +--FILE-- +<?php +function test() { + try { + $a = [1, 2, 3]; + return $a + []; + } finally { + throw new Exception; + } +} + +try { + test(); +} catch (Exception $e) { + echo "exception\n"; +} +?> +--EXPECT-- +exception diff --git a/Zend/tests/temporary_cleaning_011.phpt b/Zend/tests/temporary_cleaning_011.phpt new file mode 100644 index 0000000000..e4a6af3ab9 --- /dev/null +++ b/Zend/tests/temporary_cleaning_011.phpt @@ -0,0 +1,20 @@ +--TEST-- +Live range & lists +--FILE-- +<?php +class A { + function __destruct() { + throw new Exception(); + } +} +$b = new A(); +$x = 0; +$c = [[$x,$x]]; +try { + list($a, $b) = $c[0]; +} catch (Exception $e) { + echo "exception\n"; +} +?> +--EXPECT-- +exception diff --git a/Zend/tests/temporary_cleaning_012.phpt b/Zend/tests/temporary_cleaning_012.phpt new file mode 100644 index 0000000000..fdbea6d41d --- /dev/null +++ b/Zend/tests/temporary_cleaning_012.phpt @@ -0,0 +1,20 @@ +--TEST-- +Live range of ZEND_NEW must be assigned to correct variable +--FILE-- +<?php + +class Foo { + public static function test() { + self::$property = new self; + } +} + +try { + Foo::test(); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Access to undeclared static property: Foo::$property diff --git a/Zend/tests/try/try_finally_021.phpt b/Zend/tests/try/try_finally_021.phpt new file mode 100644 index 0000000000..ed162f40d0 --- /dev/null +++ b/Zend/tests/try/try_finally_021.phpt @@ -0,0 +1,20 @@ +--TEST-- +Live range & return from finally +--FILE-- +<?php +$array = [1]; +foreach ([0] as $_) { + foreach ($array as $v) { + try { + echo "ok\n"; + return; + } finally { + echo "ok\n"; + return; + } + } +} +?> +--EXPECT-- +ok +ok diff --git a/Zend/tests/try/try_finally_022.phpt b/Zend/tests/try/try_finally_022.phpt new file mode 100644 index 0000000000..51f6a26419 --- /dev/null +++ b/Zend/tests/try/try_finally_022.phpt @@ -0,0 +1,41 @@ +--TEST-- +Try finally (exception in "return" statement) +--FILE-- +<?php +class A { + public $x = 1; + public $y = 2; + function __destruct() { + throw new Exception(); + } +} +try{ + $a = 0; + switch ($a) { + case 0: + } + switch ($a) { + case 0: + } + switch ($a) { + case 0: + } + foreach([new stdClass()] as $x) { + foreach(new A() as $a) { + foreach([new stdClass()] as $y) { + try { + if (0) { echo "0" . (int)5; } + return $a; + } catch (Exception $e) { + echo "exception1\n"; + } + } + } + } +} catch (Exception $e) { + echo "exception2\n"; +} +?> +--EXPECT-- +exception2 + diff --git a/Zend/zend.c b/Zend/zend.c index d036152307..50cda403f6 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -622,7 +622,7 @@ static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */ zval globals; ZVAL_ARR(&globals, &EG(symbol_table)); - Z_TYPE_INFO_P(&globals) = IS_ARRAY | (IS_TYPE_SYMBOLTABLE << Z_TYPE_FLAGS_SHIFT); + Z_TYPE_INFO_P(&globals) = IS_ARRAY; ZVAL_NEW_REF(&globals, &globals); zend_hash_update(&EG(symbol_table), name, &globals); return 0; diff --git a/Zend/zend.h b/Zend/zend.h index ebaddd74b6..e886ba20d3 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -22,7 +22,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "3.0.0" +#define ZEND_VERSION "3.1.0-dev" #define ZEND_ENGINE_3 @@ -61,7 +61,7 @@ #define USED_RET() \ (!EX(prev_execute_data) || \ !ZEND_USER_CODE(EX(prev_execute_data)->func->common.type) || \ - !(EX(prev_execute_data)->opline->result_type & EXT_TYPE_UNUSED)) + (EX(prev_execute_data)->opline->result_type != IS_UNUSED)) #ifdef ZEND_ENABLE_STATIC_TSRMLS_CACHE #define ZEND_TSRMG TSRMG_STATIC @@ -89,11 +89,6 @@ ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char * # define zend_error_noreturn zend_error #endif -/* overloaded elements data types */ -#define OE_IS_ARRAY (1<<0) -#define OE_IS_OBJECT (1<<1) -#define OE_IS_METHOD (1<<2) - struct _zend_serialize_data; struct _zend_unserialize_data; diff --git a/Zend/zend_API.c b/Zend/zend_API.c index a7d19f9892..18e6e0f4f4 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -184,6 +184,8 @@ ZEND_API char *zend_get_type_by_const(int type) /* {{{ */ return "callable"; case IS_ARRAY: return "array"; + case IS_VOID: + return "void"; default: return "unknown"; } @@ -198,7 +200,7 @@ ZEND_API char *zend_zval_type_name(const zval *arg) /* {{{ */ /* }}} */ #ifdef FAST_ZPP -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_paramers_count_error(int num_args, int min_num_args, int max_num_args) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(int num_args, int min_num_args, int max_num_args) /* {{{ */ { zend_function *active_function = EG(current_execute_data)->func; const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : ""; @@ -214,7 +216,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_paramers_count_error(int num_ar } /* }}} */ -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_paramer_type_error(int num, zend_expected_type expected_type, zval *arg) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(int num, zend_expected_type expected_type, zval *arg) /* {{{ */ { const char *space; const char *class_name = get_active_class_name(&space); @@ -228,7 +230,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_paramer_type_error(int num, zen } /* }}} */ -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_paramer_class_error(int num, char *name, zval *arg) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(int num, char *name, zval *arg) /* {{{ */ { const char *space; const char *class_name = get_active_class_name(&space); @@ -368,11 +370,7 @@ ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_weak(zval *arg, zend_long *de if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) { return 0; } - if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) { - *dest = (Z_DVAL_P(arg) > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN; - } else { - *dest = zend_dval_to_lval(Z_DVAL_P(arg)); - } + *dest = zend_dval_to_lval_cap(Z_DVAL_P(arg)); } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) { double d; int type; @@ -382,11 +380,7 @@ ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_weak(zval *arg, zend_long *de if (UNEXPECTED(zend_isnan(d))) { return 0; } - if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) { - *dest = (d > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN; - } else { - *dest = zend_dval_to_lval(d); - } + *dest = zend_dval_to_lval_cap(d); } else { return 0; } @@ -1128,12 +1122,13 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */ zend_class_entry **scope = EG(current_execute_data) ? &EG(scope) : &CG(active_class_entry); zend_class_entry *old_scope = *scope; zend_class_entry *ce; + zend_class_constant *c; zval *val; zend_property_info *prop_info; *scope = class_type; - ZEND_HASH_FOREACH_VAL(&class_type->constants_table, val) { - ZVAL_DEREF(val); + ZEND_HASH_FOREACH_PTR(&class_type->constants_table, c) { + val = &c->value; if (Z_CONSTANT_P(val)) { if (UNEXPECTED(zval_update_constant_ex(val, 1, class_type) != SUCCESS)) { return FAILURE; @@ -3424,7 +3419,6 @@ ZEND_API int zend_fcall_info_init(zval *callable, uint check_flags, zend_fcall_i fci->param_count = 0; fci->params = NULL; fci->no_separation = 1; - fci->symbol_table = NULL; return SUCCESS; } @@ -3743,13 +3737,51 @@ ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, const char *nam } /* }}} */ -ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name, size_t name_length, zval *value) /* {{{ */ +ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *name, zval *value, int access_type, zend_string *doc_comment) /* {{{ */ { + zend_class_constant *c; + + if (ce->ce_flags & ZEND_ACC_INTERFACE) { + if (access_type != ZEND_ACC_PUBLIC) { + zend_error_noreturn(E_COMPILE_ERROR, "Access type for interface constant %s::%s must be public", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + } + } + + if (zend_string_equals_literal_ci(name, "class")) { + zend_error_noreturn(ce->type == ZEND_INTERNAL_CLASS ? E_CORE_ERROR : E_COMPILE_ERROR, + "A class constant must not be called 'class'; it is reserved for class name fetching"); + } + + if (ce->type == ZEND_INTERNAL_CLASS) { + c = pemalloc(sizeof(zend_class_constant), 1); + } else { + c = zend_arena_alloc(&CG(arena), sizeof(zend_class_constant)); + } + ZVAL_COPY_VALUE(&c->value, value); + Z_ACCESS_FLAGS(c->value) = access_type; + c->doc_comment = doc_comment; + c->ce = ce; if (Z_CONSTANT_P(value)) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } - return zend_hash_str_update(&ce->constants_table, name, name_length, value) ? - SUCCESS : FAILURE; + + if (!zend_hash_add_ptr(&ce->constants_table, name, c)) { + zend_error_noreturn(ce->type == ZEND_INTERNAL_CLASS ? E_CORE_ERROR : E_COMPILE_ERROR, + "Cannot redefine class constant %s::%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + } + + return SUCCESS; +} +/* }}} */ + +ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name, size_t name_length, zval *value) /* {{{ */ +{ + int ret; + + zend_string *key = zend_string_init(name, name_length, ce->type & ZEND_INTERNAL_CLASS); + ret = zend_declare_class_constant_ex(ce, key, value, ZEND_ACC_PUBLIC, NULL); + zend_string_release(key); + return ret; } /* }}} */ diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 2c251fdb16..40c814f71d 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -45,7 +45,6 @@ typedef struct _zend_fcall_info { size_t size; HashTable *function_table; zval function_name; - zend_array *symbol_table; zval *retval; zval *params; zend_object *object; @@ -324,6 +323,7 @@ ZEND_API int zend_declare_property_double(zend_class_entry *ce, const char *name ZEND_API int zend_declare_property_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value, int access_type); ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, const char *name, size_t name_length, const char *value, size_t value_len, int access_type); +ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *name, zval *value, int access_type, zend_string *doc_comment); ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name, size_t name_length, zval *value); ZEND_API int zend_declare_class_constant_null(zend_class_entry *ce, const char *name, size_t name_length); ZEND_API int zend_declare_class_constant_long(zend_class_entry *ce, const char *name, size_t name_length, zend_long value); @@ -469,7 +469,10 @@ ZEND_API int add_property_zval_ex(zval *arg, const char *key, size_t key_len, zv ZEND_API int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[]); -ZEND_API int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[], int no_separation, zend_array *symbol_table); +ZEND_API int _call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[], int no_separation); + +#define call_user_function_ex(function_table, object, function_name, retval_ptr, param_count, params, no_separation, symbol_table) \ + _call_user_function_ex(function_table, object, function_name, retval_ptr, param_count, params, no_separation) ZEND_API extern const zend_fcall_info empty_fcall_info; ZEND_API extern const zend_fcall_info_cache empty_fcall_info_cache; @@ -692,9 +695,9 @@ typedef enum _zend_expected_type { Z_EXPECTED_LAST } zend_expected_type; -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_paramers_count_error(int num_args, int min_num_args, int max_num_args); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_paramer_type_error(int num, zend_expected_type expected_type, zval *arg); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_paramer_class_error(int num, char *name, zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(int num_args, int min_num_args, int max_num_args); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(int num, zend_expected_type expected_type, zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(int num, char *name, zval *arg); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(int severity, int num, char *error); #define ZPP_ERROR_OK 0 @@ -729,7 +732,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(int severity, in (UNEXPECTED(_num_args > _max_num_args) && \ EXPECTED(_max_num_args >= 0))) { \ if (!(_flags & ZEND_PARSE_PARAMS_QUIET)) { \ - zend_wrong_paramers_count_error(_num_args, _min_num_args, _max_num_args); \ + zend_wrong_parameters_count_error(_num_args, _min_num_args, _max_num_args); \ } \ error_code = ZPP_ERROR_FAILURE; \ break; \ @@ -747,9 +750,9 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(int severity, in if (error_code == ZPP_ERROR_WRONG_CALLBACK) { \ zend_wrong_callback_error(E_WARNING, _i, _error); \ } else if (error_code == ZPP_ERROR_WRONG_CLASS) { \ - zend_wrong_paramer_class_error(_i, _error, _arg); \ + zend_wrong_parameter_class_error(_i, _error, _arg); \ } else if (error_code == ZPP_ERROR_WRONG_ARG) { \ - zend_wrong_paramer_type_error(_i, _expected_type, _arg); \ + zend_wrong_parameter_type_error(_i, _expected_type, _arg); \ } \ } \ failure; \ diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 0daec66069..ec771003c0 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -124,7 +124,6 @@ enum _zend_ast_kind { ZEND_AST_SWITCH, ZEND_AST_SWITCH_CASE, ZEND_AST_DECLARE, - ZEND_AST_CONST_ELEM, ZEND_AST_USE_TRAIT, ZEND_AST_TRAIT_PRECEDENCE, ZEND_AST_METHOD_REFERENCE, @@ -142,6 +141,7 @@ enum _zend_ast_kind { ZEND_AST_CATCH, ZEND_AST_PARAM, ZEND_AST_PROP_ELEM, + ZEND_AST_CONST_ELEM, /* 4 child nodes */ ZEND_AST_FOR = 4 << ZEND_AST_NUM_CHILDREN_SHIFT, diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index a576455fa3..a35c519c03 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -31,6 +31,12 @@ #undef ZEND_TEST_EXCEPTIONS +#if ZEND_DEBUG +static zend_class_entry *zend_test_interface; +static zend_class_entry *zend_test_class; +static zend_object_handlers zend_test_class_handlers; +#endif + static ZEND_FUNCTION(zend_version); static ZEND_FUNCTION(func_num_args); static ZEND_FUNCTION(func_get_arg); @@ -257,6 +263,51 @@ ZEND_END_ARG_INFO() /* }}} */ +#if ZEND_DEBUG +static zend_object *zend_test_class_new(zend_class_entry *class_type) /* {{{ */ { + zend_object *obj = zend_objects_new(class_type); + obj->handlers = &zend_test_class_handlers; + return obj; +} +/* }}} */ + +static zend_function *zend_test_class_method_get(zend_object **object, zend_string *name, const zval *key) /* {{{ */ { + zend_internal_function *fptr = emalloc(sizeof(zend_internal_function)); + fptr->type = ZEND_OVERLOADED_FUNCTION_TEMPORARY; + fptr->num_args = 1; + fptr->arg_info = NULL; + fptr->scope = (*object)->ce; + fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER; + fptr->function_name = zend_string_copy(name); + fptr->handler = ZEND_FN(zend_test_func); + zend_set_function_arg_flags((zend_function*)fptr); + + return (zend_function*)fptr; +} +/* }}} */ + +static zend_function *zend_test_class_static_method_get(zend_class_entry *ce, zend_string *name) /* {{{ */ { + zend_internal_function *fptr = emalloc(sizeof(zend_internal_function)); + fptr->type = ZEND_OVERLOADED_FUNCTION; + fptr->num_args = 1; + fptr->arg_info = NULL; + fptr->scope = ce; + fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_STATIC; + fptr->function_name = name; + fptr->handler = ZEND_FN(zend_test_func); + zend_set_function_arg_flags((zend_function*)fptr); + + return (zend_function*)fptr; +} +/* }}} */ + +static int zend_test_class_call_method(zend_string *method, zend_object *object, INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { + RETVAL_STR(zend_string_copy(method)); + return 0; +} +/* }}} */ +#endif + static const zend_function_entry builtin_functions[] = { /* {{{ */ ZEND_FE(zend_version, arginfo_zend__void) ZEND_FE(func_num_args, arginfo_zend__void) @@ -339,6 +390,21 @@ ZEND_MINIT_FUNCTION(core) { /* {{{ */ zend_register_default_classes(); +#if ZEND_DEBUG + INIT_CLASS_ENTRY(class_entry, "_ZendTestInterface", NULL); + zend_test_interface = zend_register_internal_interface(&class_entry); + zend_declare_class_constant_long(zend_test_interface, ZEND_STRL("DUMMY"), 0); + INIT_CLASS_ENTRY(class_entry, "_ZendTestClass", NULL); + zend_test_class = zend_register_internal_class_ex(&class_entry, NULL); + zend_class_implements(zend_test_class, 1, zend_test_interface); + zend_test_class->create_object = zend_test_class_new; + zend_test_class->get_static_method = zend_test_class_static_method_get; + + memcpy(&zend_test_class_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + zend_test_class_handlers.get_method = zend_test_class_method_get; + zend_test_class_handlers.call_method = zend_test_class_call_method; +#endif + return SUCCESS; } /* }}} */ @@ -2036,17 +2102,16 @@ ZEND_FUNCTION(zend_test_func) { zval *arg1, *arg2; - zend_get_parameters(ZEND_NUM_ARGS(), 2, &arg1, &arg2); + zend_parse_parameters(ZEND_NUM_ARGS(), "|zz", &arg1, &arg2); } ZEND_FUNCTION(zend_test_func2) { zval *arg1, *arg2; - zend_get_parameters(ZEND_NUM_ARGS(), 2, &arg1, &arg2); + zend_parse_parameters(ZEND_NUM_ARGS(), "|zz", &arg1, &arg2); } - #ifdef ZTS ZEND_FUNCTION(zend_thread_id) { diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index def114c4ec..d52d0b5c25 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -566,11 +566,8 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent closure->func.common.prototype = (zend_function*)closure; closure->func.common.fn_flags |= ZEND_ACC_CLOSURE; if (closure->func.op_array.static_variables) { - HashTable *static_variables = closure->func.op_array.static_variables; - - ALLOC_HASHTABLE(closure->func.op_array.static_variables); - zend_hash_init(closure->func.op_array.static_variables, zend_hash_num_elements(static_variables), NULL, ZVAL_PTR_DTOR, 0); - zend_hash_apply_with_arguments(static_variables, zval_copy_static_var, 1, closure->func.op_array.static_variables); + closure->func.op_array.static_variables = + zend_array_dup(closure->func.op_array.static_variables); } if (UNEXPECTED(!closure->func.op_array.run_time_cache)) { closure->func.op_array.run_time_cache = func->op_array.run_time_cache = zend_arena_alloc(&CG(arena), func->op_array.cache_size); @@ -625,6 +622,14 @@ ZEND_API void zend_create_fake_closure(zval *res, zend_function *func, zend_clas } /* }}} */ +void zend_closure_bind_var(zval *closure_zv, zend_string *var_name, zval *var) /* {{{ */ +{ + zend_closure *closure = (zend_closure *) Z_OBJ_P(closure_zv); + HashTable *static_variables = closure->func.op_array.static_variables; + zend_hash_update(static_variables, var_name, var); +} +/* }}} */ + /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_closures.h b/Zend/zend_closures.h index 095dc54c24..7f8bac430c 100644 --- a/Zend/zend_closures.h +++ b/Zend/zend_closures.h @@ -25,6 +25,7 @@ BEGIN_EXTERN_C() void zend_register_closure_ce(void); +void zend_closure_bind_var(zval *closure_zv, zend_string *var_name, zval *var); extern ZEND_API zend_class_entry *zend_ce_closure; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index bc33e07d1f..1401a6e051 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -60,7 +60,7 @@ typedef struct _zend_loop_var { uint32_t var_num; union { uint32_t try_catch_offset; - uint32_t brk_cont_offset; + uint32_t live_range_offset; } u; } zend_loop_var; @@ -86,6 +86,8 @@ ZEND_API zend_compiler_globals compiler_globals; ZEND_API zend_executor_globals executor_globals; #endif +static zend_op *zend_emit_op(znode *result, zend_uchar opcode, znode *op1, znode *op2); + static void zend_destroy_property_info_internal(zval *zv) /* {{{ */ { zend_property_info *property_info = Z_PTR_P(zv); @@ -95,6 +97,12 @@ 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; @@ -151,6 +159,7 @@ static const struct reserved_class_name reserved_class_names[] = { {ZEND_STRL("static")}, {ZEND_STRL("string")}, {ZEND_STRL("true")}, + {ZEND_STRL("void")}, {NULL, 0} }; @@ -194,6 +203,7 @@ static const builtin_type_info builtin_types[] = { {ZEND_STRL("float"), IS_DOUBLE}, {ZEND_STRL("string"), IS_STRING}, {ZEND_STRL("bool"), _IS_BOOL}, + {ZEND_STRL("void"), IS_VOID}, {NULL, 0, IS_UNDEF} }; @@ -221,16 +231,22 @@ void zend_oparray_context_begin(zend_oparray_context *prev_context) /* {{{ */ CG(context).opcodes_size = INITIAL_OP_ARRAY_SIZE; CG(context).vars_size = 0; CG(context).literals_size = 0; - CG(context).current_brk_cont = -1; CG(context).backpatch_count = 0; CG(context).in_finally = 0; CG(context).fast_call_var = -1; + CG(context).current_brk_cont = -1; + CG(context).last_brk_cont = 0; + CG(context).brk_cont_array = NULL; CG(context).labels = NULL; } /* }}} */ void zend_oparray_context_end(zend_oparray_context *prev_context) /* {{{ */ { + if (CG(context).brk_cont_array) { + efree(CG(context).brk_cont_array); + CG(context).brk_cont_array = NULL; + } if (CG(context).labels) { zend_hash_destroy(CG(context).labels); FREE_HASHTABLE(CG(context).labels); @@ -570,22 +586,111 @@ void zend_stop_lexing(void) LANG_SCNG(yy_cursor) = LANG_SCNG(yy_limit); } +static uint32_t zend_start_live_range(zend_op_array *op_array, uint32_t start) /* {{{ */ +{ + zend_live_range *range; + + op_array->last_live_range++; + op_array->live_range = erealloc(op_array->live_range, sizeof(zend_live_range) * op_array->last_live_range); + range = op_array->live_range + op_array->last_live_range - 1; + range->start = start; + return op_array->last_live_range - 1; +} +/* }}} */ + +static uint32_t zend_start_live_range_ex(zend_op_array *op_array, uint32_t start) /* {{{ */ +{ + if (op_array->last_live_range == 0 || + op_array->live_range[op_array->last_live_range - 1].start <= start) { + return zend_start_live_range(op_array, start); + } else { + /* Live ranges have to be sorted by "start" field */ + uint32_t n = op_array->last_live_range; + + /* move early ranges to make a room */ + op_array->last_live_range = n + 1; + op_array->live_range = erealloc(op_array->live_range, sizeof(zend_live_range) * op_array->last_live_range); + do { + op_array->live_range[n] = op_array->live_range[n-1]; + n--; + } while (n != 0 && op_array->live_range[n-1].start > start); + + /* initialize new range */ + op_array->live_range[n].start = start; + + /* update referens to live-ranges from stack */ + if (!zend_stack_is_empty(&CG(loop_var_stack))) { + zend_loop_var *loop_var = zend_stack_top(&CG(loop_var_stack)); + zend_loop_var *base = zend_stack_base(&CG(loop_var_stack)); + int check_opcodes = 0; + + for (; loop_var >= base; loop_var--) { + if (loop_var->opcode == ZEND_RETURN) { + /* Stack separator */ + break; + } else if (loop_var->opcode == ZEND_FREE || + loop_var->opcode == ZEND_FE_FREE) { + if (loop_var->u.live_range_offset >= n) { + loop_var->u.live_range_offset++; + check_opcodes = 1; + } else { + break; + } + } + } + + /* update previously generated FREE/FE_FREE opcodes */ + if (check_opcodes) { + zend_op *opline = op_array->opcodes + op_array->live_range[n+1].start; + zend_op *end = op_array->opcodes + op_array->last; + + while (opline < end) { + if ((opline->opcode == ZEND_FREE || + opline->opcode == ZEND_FE_FREE) && + (opline->extended_value & ZEND_FREE_ON_RETURN) && + opline->op2.num >= n) { + opline->op2.num++; + } + opline++; + } + } + } + return n; + } +} +/* }}} */ + +static void zend_end_live_range(zend_op_array *op_array, uint32_t offset, uint32_t end, uint32_t kind, uint32_t var) /* {{{ */ +{ + zend_live_range *range = op_array->live_range + offset; + + if (range->start == end && offset == op_array->last_live_range - 1) { + op_array->last_live_range--; + } else { + range->end = end; + range->var = (var * sizeof(zval)) | kind; + } +} +/* }}} */ + static inline void zend_begin_loop(zend_uchar free_opcode, const znode *loop_var) /* {{{ */ { zend_brk_cont_element *brk_cont_element; int parent = CG(context).current_brk_cont; zend_loop_var info = {0}; - CG(context).current_brk_cont = CG(active_op_array)->last_brk_cont; - brk_cont_element = get_next_brk_cont_element(CG(active_op_array)); + CG(context).current_brk_cont = CG(context).last_brk_cont; + brk_cont_element = get_next_brk_cont_element(); brk_cont_element->parent = parent; if (loop_var && (loop_var->op_type & (IS_VAR|IS_TMP_VAR))) { + uint32_t start = get_next_op_number(CG(active_op_array)); + info.opcode = free_opcode; info.var_type = loop_var->op_type; info.var_num = loop_var->u.op.var; - info.u.brk_cont_offset = CG(context).current_brk_cont; - brk_cont_element->start = get_next_op_number(CG(active_op_array)); + info.u.live_range_offset = zend_start_live_range(CG(active_op_array), start); + brk_cont_element->start = start; } else { info.opcode = ZEND_NOP; /* The start field is used to free temporary variables in case of exceptions. @@ -597,14 +702,22 @@ static inline void zend_begin_loop(zend_uchar free_opcode, const znode *loop_var } /* }}} */ -static inline void zend_end_loop(int cont_addr) /* {{{ */ +static inline void zend_end_loop(int cont_addr, const znode *var_node) /* {{{ */ { + uint32_t end = get_next_op_number(CG(active_op_array)); zend_brk_cont_element *brk_cont_element - = &CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont]; + = &CG(context).brk_cont_array[CG(context).current_brk_cont]; brk_cont_element->cont = cont_addr; - brk_cont_element->brk = get_next_op_number(CG(active_op_array)); + brk_cont_element->brk = end; CG(context).current_brk_cont = brk_cont_element->parent; + if (brk_cont_element->start != -1) { + zend_loop_var *loop_var = zend_stack_top(&CG(loop_var_stack)); + zend_end_live_range(CG(active_op_array), loop_var->u.live_range_offset, end, + loop_var->opcode == ZEND_FE_FREE ? ZEND_LIVE_LOOP : ZEND_LIVE_TMPVAR, + var_node->u.op.var); + } + zend_stack_del_top(&CG(loop_var_stack)); } /* }}} */ @@ -624,11 +737,7 @@ void zend_do_free(znode *op1) /* {{{ */ } } - opline = get_next_op(CG(active_op_array)); - - opline->opcode = ZEND_FREE; - SET_NODE(opline->op1, op1); - SET_UNUSED(opline->op2); + zend_emit_op(NULL, ZEND_FREE, op1, NULL); } else if (op1->op_type == IS_VAR) { zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1]; while (opline->opcode == ZEND_END_SILENCE || @@ -640,38 +749,27 @@ void zend_do_free(znode *op1) /* {{{ */ && opline->result.var == op1->u.op.var) { if (opline->opcode == ZEND_FETCH_R || opline->opcode == ZEND_FETCH_DIM_R || - opline->opcode == ZEND_FETCH_OBJ_R) { + opline->opcode == ZEND_FETCH_OBJ_R || + opline->opcode == ZEND_FETCH_STATIC_PROP_R) { /* It's very rare and useless case. It's better to use additional FREE opcode and simplify the FETCH handlers their selves */ - opline = get_next_op(CG(active_op_array)); - opline->opcode = ZEND_FREE; - SET_NODE(opline->op1, op1); - SET_UNUSED(opline->op2); + zend_emit_op(NULL, ZEND_FREE, op1, NULL); } else { - opline->result_type |= EXT_TYPE_UNUSED; + opline->result_type = IS_UNUSED; } } else { while (opline >= CG(active_op_array)->opcodes) { if (opline->opcode == ZEND_FETCH_LIST && opline->op1_type == IS_VAR && opline->op1.var == op1->u.op.var) { - opline = get_next_op(CG(active_op_array)); - - opline->opcode = ZEND_FREE; - SET_NODE(opline->op1, op1); - SET_UNUSED(opline->op2); + zend_emit_op(NULL, ZEND_FREE, op1, NULL); return; } if (opline->result_type == IS_VAR && opline->result.var == op1->u.op.var) { if (opline->opcode == ZEND_NEW) { - opline->result_type |= EXT_TYPE_UNUSED; - opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1]; - while (opline->opcode != ZEND_DO_FCALL || opline->op1.num != ZEND_CALL_CTOR) { - opline--; - } - opline->op1.num |= ZEND_CALL_CTOR_RESULT_UNUSED; + zend_emit_op(NULL, ZEND_FREE, op1, NULL); } break; } @@ -951,24 +1049,24 @@ 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 *op1, *op2; + zval *lcname, *rtd_key; if (compile_time) { - op1 = CT_CONSTANT_EX(op_array, opline->op1.constant); - op2 = CT_CONSTANT_EX(op_array, opline->op2.constant); + lcname = CT_CONSTANT_EX(op_array, opline->op1.constant); + rtd_key = lcname + 1; } else { - op1 = RT_CONSTANT(op_array, opline->op1); - op2 = RT_CONSTANT(op_array, opline->op2); + lcname = RT_CONSTANT(op_array, opline->op1); + rtd_key = lcname + 1; } - function = zend_hash_find_ptr(function_table, Z_STR_P(op1)); + function = zend_hash_find_ptr(function_table, Z_STR_P(rtd_key)); 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(op2), new_function) == NULL) { + 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(op2))) != NULL + if ((old_function = zend_hash_find_ptr(function_table, Z_STR_P(lcname))) != NULL && 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)", @@ -992,21 +1090,21 @@ 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 *op1, *op2; + zval *lcname, *rtd_key; if (compile_time) { - op1 = CT_CONSTANT_EX(op_array, opline->op1.constant); - op2 = CT_CONSTANT_EX(op_array, opline->op2.constant); + lcname = CT_CONSTANT_EX(op_array, opline->op1.constant); + rtd_key = lcname + 1; } else { - op1 = RT_CONSTANT(op_array, opline->op1); - op2 = RT_CONSTANT(op_array, opline->op2); + lcname = RT_CONSTANT(op_array, opline->op1); + rtd_key = lcname + 1; } - if ((ce = zend_hash_find_ptr(class_table, Z_STR_P(op1))) == NULL) { - zend_error_noreturn(E_COMPILE_ERROR, "Internal Zend error - Missing class information for %s", Z_STRVAL_P(op1)); + if ((ce = zend_hash_find_ptr(class_table, Z_STR_P(rtd_key))) == NULL) { + zend_error_noreturn(E_COMPILE_ERROR, "Internal Zend error - Missing class information for %s", Z_STRVAL_P(rtd_key)); return NULL; } ce->refcount++; - if (zend_hash_add_ptr(class_table, Z_STR_P(op2), ce) == NULL) { + if (zend_hash_add_ptr(class_table, Z_STR_P(lcname), ce) == NULL) { ce->refcount--; if (!compile_time) { /* If we're in compile time, in practice, it's quite possible @@ -1029,17 +1127,17 @@ 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 *op1, *op2; + zval *lcname, *rtd_key; if (compile_time) { - op1 = CT_CONSTANT_EX(op_array, opline->op1.constant); - op2 = CT_CONSTANT_EX(op_array, opline->op2.constant); + lcname = CT_CONSTANT_EX(op_array, opline->op1.constant); + rtd_key = lcname + 1; } else { - op1 = RT_CONSTANT(op_array, opline->op1); - op2 = RT_CONSTANT(op_array, opline->op2); + lcname = RT_CONSTANT(op_array, opline->op1); + rtd_key = lcname + 1; } - ce = zend_hash_find_ptr(class_table, Z_STR_P(op1)); + ce = zend_hash_find_ptr(class_table, Z_STR_P(rtd_key)); if (!ce) { if (!compile_time) { @@ -1048,12 +1146,12 @@ ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array * so we shut up about it. This allows the if (!defined('FOO')) { return; } * approach to work. */ - zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(Z_OBJCE_P(op2)), Z_STRVAL_P(op2)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s, because the name is already in use", zend_get_object_type(Z_OBJCE_P(lcname)), Z_STRVAL_P(lcname)); } return NULL; } - if (zend_hash_exists(class_table, Z_STR_P(op2))) { + 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)); } @@ -1062,7 +1160,7 @@ ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array ce->refcount++; /* Register the derived class */ - if (zend_hash_add_ptr(class_table, Z_STR_P(op2), ce) == NULL) { + if (zend_hash_add_ptr(class_table, Z_STR_P(lcname), ce) == NULL) { 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)); } return ce; @@ -1136,9 +1234,9 @@ void zend_do_early_binding(void) /* {{{ */ return; } - zend_hash_del(table, Z_STR_P(CT_CONSTANT(opline->op1))); + zend_hash_del(table, Z_STR_P(CT_CONSTANT(opline->op1)+1)); + zend_del_literal(CG(active_op_array), opline->op1.constant+1); zend_del_literal(CG(active_op_array), opline->op1.constant); - zend_del_literal(CG(active_op_array), opline->op2.constant); MAKE_NOP(opline); } /* }}} */ @@ -1149,19 +1247,19 @@ static void zend_mark_function_as_generator() /* {{{ */ zend_error_noreturn(E_COMPILE_ERROR, "The \"yield\" expression can only be used inside a function"); } + if (CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { const char *msg = "Generators may only declare a return type of Generator, Iterator or Traversable, %s is not permitted"; - if (!CG(active_op_array)->arg_info[-1].class_name) { - zend_error_noreturn(E_COMPILE_ERROR, msg, - zend_get_type_by_const(CG(active_op_array)->arg_info[-1].type_hint)); + zend_arg_info return_info = CG(active_op_array)->arg_info[-1]; + + if (!return_info.class_name) { + zend_error_noreturn(E_COMPILE_ERROR, msg, zend_get_type_by_const(return_info.type_hint)); } - if (!(ZSTR_LEN(CG(active_op_array)->arg_info[-1].class_name) == sizeof("Traversable")-1 - && zend_binary_strcasecmp(ZSTR_VAL(CG(active_op_array)->arg_info[-1].class_name), sizeof("Traversable")-1, "Traversable", sizeof("Traversable")-1) == 0) && - !(ZSTR_LEN(CG(active_op_array)->arg_info[-1].class_name) == sizeof("Iterator")-1 - && zend_binary_strcasecmp(ZSTR_VAL(CG(active_op_array)->arg_info[-1].class_name), sizeof("Iterator")-1, "Iterator", sizeof("Iterator")-1) == 0) && - !(ZSTR_LEN(CG(active_op_array)->arg_info[-1].class_name) == sizeof("Generator")-1 - && zend_binary_strcasecmp(ZSTR_VAL(CG(active_op_array)->arg_info[-1].class_name), sizeof("Generator")-1, "Generator", sizeof("Generator")-1) == 0)) { - zend_error_noreturn(E_COMPILE_ERROR, msg, ZSTR_VAL(CG(active_op_array)->arg_info[-1].class_name)); + + if (!zend_string_equals_literal_ci(return_info.class_name, "Traversable") + && !zend_string_equals_literal_ci(return_info.class_name, "Iterator") + && !zend_string_equals_literal_ci(return_info.class_name, "Generator")) { + zend_error_noreturn(E_COMPILE_ERROR, msg, ZSTR_VAL(return_info.class_name)); } } @@ -1415,14 +1513,15 @@ static zend_bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_a static zend_bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, zend_string *name) /* {{{ */ { uint32_t fetch_type = zend_get_class_fetch_type(class_name); + zend_class_constant *cc; zval *c; if (class_name_refers_to_active_ce(class_name, fetch_type)) { - c = zend_hash_find(&CG(active_class_entry)->constants_table, name); + cc = zend_hash_find_ptr(&CG(active_class_entry)->constants_table, name); } else if (fetch_type == ZEND_FETCH_CLASS_DEFAULT && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) { zend_class_entry *ce = zend_hash_find_ptr_lc(CG(class_table), ZSTR_VAL(class_name), ZSTR_LEN(class_name)); if (ce) { - c = zend_hash_find(&ce->constants_table, name); + cc = zend_hash_find_ptr(&ce->constants_table, name); } else { return 0; } @@ -1434,8 +1533,14 @@ static zend_bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, return 0; } + if (!cc || !zend_verify_const_access(cc, CG(active_class_entry))) { + return 0; + } + + c = &cc->value; + /* Substitute case-sensitive (or lowercase) persistent class constants */ - if (c && Z_TYPE_P(c) < IS_OBJECT) { + if (Z_TYPE_P(c) < IS_OBJECT) { ZVAL_DUP(zv, c); return 1; } @@ -1616,7 +1721,6 @@ again: ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers) /* {{{ */ { zend_bool persistent_hashes = (ce->type == ZEND_INTERNAL_CLASS) ? 1 : 0; - dtor_func_t zval_ptr_dtor_func = ((persistent_hashes) ? ZVAL_INTERNAL_PTR_DTOR : ZVAL_PTR_DTOR); ce->refcount = 1; ce->ce_flags = ZEND_ACC_CONSTANTS_UPDATED; @@ -1628,7 +1732,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, zval_ptr_dtor_func, 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->function_table, 8, NULL, ZEND_FUNCTION_DTOR, persistent_hashes, 0); if (ce->type == ZEND_INTERNAL_CLASS) { @@ -1820,25 +1924,26 @@ 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; + switch (type & BP_VAR_MASK) { case BP_VAR_R: return; case BP_VAR_W: - case BP_VAR_REF: - opline->opcode += 3; + opline->opcode += 1 * factor; return; case BP_VAR_RW: - opline->opcode += 6; + opline->opcode += 2 * factor; return; case BP_VAR_IS: - opline->opcode += 9; + opline->opcode += 3 * factor; return; case BP_VAR_FUNC_ARG: - opline->opcode += 12; + opline->opcode += 4 * factor; opline->extended_value |= type >> BP_VAR_SHIFT; return; case BP_VAR_UNSET: - opline->opcode += 15; + opline->opcode += 5 * factor; return; EMPTY_SWITCH_DEFAULT_CASE() } @@ -1861,6 +1966,136 @@ static inline void zend_make_tmp_result(znode *result, zend_op *opline) /* {{{ * } /* }}} */ +static void zend_find_live_range(zend_op *opline, zend_uchar type, uint32_t var) /* {{{ */ +{ + zend_op *def = opline; + + while (def != CG(active_op_array)->opcodes) { + def--; + if (def->result_type == type && def->result.var == var) { + if (def->opcode == ZEND_ADD_ARRAY_ELEMENT || + def->opcode == ZEND_ROPE_ADD) { + /* not a real definition */ + continue; + } else if (def->opcode == ZEND_JMPZ_EX || + def->opcode == ZEND_JMPNZ_EX || + def->opcode == ZEND_BOOL || + def->opcode == ZEND_BOOL_NOT) { + /* result IS_BOOL, it does't have to be destroyed */ + break; + } else if (def->opcode == ZEND_DECLARE_CLASS || + def->opcode == ZEND_DECLARE_INHERITED_CLASS || + def->opcode == ZEND_DECLARE_INHERITED_CLASS_DELAYED || + def->opcode == ZEND_DECLARE_ANON_CLASS || + def->opcode == ZEND_DECLARE_ANON_INHERITED_CLASS) { + /* classes don't have to be destroyed */ + break; + } else if (def->opcode == ZEND_FAST_CALL) { + /* fast_calls don't have to be destroyed */ + break; + } else if (def->opcode == ZEND_NEW) { + /* Objects created via ZEND_NEW are only fully initialized + * after the DO_FCALL (constructor call) */ + def = CG(active_op_array)->opcodes + def->op2.opline_num - 1; + if (def + 1 == opline) { + break; + } + } + + zend_end_live_range(CG(active_op_array), + zend_start_live_range_ex(CG(active_op_array), + def + 1 - CG(active_op_array)->opcodes), + opline - CG(active_op_array)->opcodes, + ZEND_LIVE_TMPVAR, var); + break; + } + } +} +/* }}} */ + +static zend_always_inline int zend_is_def_range(zend_op *opline, zend_uchar type, uint32_t var) /* {{{ */ +{ + while (1) { + if (opline->result_type == type && opline->result.var == var) { + return opline->opcode != ZEND_ADD_ARRAY_ELEMENT && + opline->opcode != ZEND_ROPE_ADD; + } else if (opline->opcode == ZEND_OP_DATA) { + return (opline-1)->result_type == type && + (opline-1)->result.var == var; + } else if (opline->opcode == ZEND_END_SILENCE || + opline->opcode == ZEND_NOP || + opline->opcode == ZEND_EXT_NOP || + opline->opcode == ZEND_EXT_STMT || + opline->opcode == ZEND_EXT_FCALL_BEGIN || + opline->opcode == ZEND_EXT_FCALL_END || + opline->opcode == ZEND_TICKS) { + opline--; + } else { + return 0; + } + } +} +/* }}} */ + +static void zend_check_live_ranges(zend_op *opline) /* {{{ */ +{ + if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) && + !zend_is_def_range(opline - 1, opline->op1_type, opline->op1.var)) { + + if (opline->opcode == ZEND_OP_DATA) { + if (!zend_is_def_range(opline - 2, opline->op1_type, opline->op1.var)) { + zend_find_live_range(opline - 1, opline->op1_type, opline->op1.var); + } + } else if (opline->opcode == ZEND_INIT_STATIC_METHOD_CALL || + opline->opcode == ZEND_NEW || + opline->opcode == ZEND_FETCH_CLASS_CONSTANT || + opline->opcode == ZEND_ADD_INTERFACE || + opline->opcode == ZEND_ADD_TRAIT || + opline->opcode == ZEND_BIND_TRAITS || + opline->opcode == ZEND_VERIFY_ABSTRACT_CLASS) { + /* classes don't have to be destroyed */ + } else if (opline->opcode == ZEND_FAST_RET) { + /* fast_calls don't have to be destroyed */ + } else if (opline->opcode == ZEND_CASE || + opline->opcode == ZEND_FE_FETCH_R || + opline->opcode == ZEND_FE_FETCH_RW || + opline->opcode == ZEND_FE_FREE || + opline->opcode == ZEND_ROPE_ADD || + opline->opcode == ZEND_ROPE_END || + opline->opcode == ZEND_END_SILENCE || + opline->opcode == ZEND_FETCH_LIST || + opline->opcode == ZEND_VERIFY_RETURN_TYPE || + opline->opcode == ZEND_BIND_LEXICAL) { + /* these opcodes are handled separately */ + } else { + zend_find_live_range(opline, opline->op1_type, opline->op1.var); + } + } + + if ((opline->op2_type & (IS_VAR|IS_TMP_VAR)) && + !zend_is_def_range(opline - 1, opline->op2_type, opline->op2.var)) { + + if (opline->opcode == ZEND_OP_DATA) { + if (!zend_is_def_range(opline - 2, opline->op2_type, opline->op2.var)) { + zend_find_live_range(opline-1, opline->op2_type, opline->op2.var); + } + } else if (opline->opcode == ZEND_FETCH_STATIC_PROP_R || + opline->opcode == ZEND_FETCH_STATIC_PROP_W || + opline->opcode == ZEND_FETCH_STATIC_PROP_RW || + opline->opcode == ZEND_FETCH_STATIC_PROP_IS || + opline->opcode == ZEND_FETCH_STATIC_PROP_FUNC_ARG || + opline->opcode == ZEND_FETCH_STATIC_PROP_UNSET || + opline->opcode == ZEND_UNSET_STATIC_PROP || + opline->opcode == ZEND_ISSET_ISEMPTY_STATIC_PROP || + opline->opcode == ZEND_INSTANCEOF) { + /* classes don't have to be destroyed */ + } else { + zend_find_live_range(opline, opline->op2_type, opline->op2.var); + } + } +} +/* }}} */ + static zend_op *zend_emit_op(znode *result, zend_uchar opcode, znode *op1, znode *op2) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array)); @@ -1878,6 +2113,8 @@ static zend_op *zend_emit_op(znode *result, zend_uchar opcode, znode *op1, znode SET_NODE(opline->op2, op2); } + zend_check_live_ranges(opline); + if (result) { zend_make_var_result(result, opline); } @@ -1902,6 +2139,8 @@ static zend_op *zend_emit_op_tmp(znode *result, zend_uchar opcode, znode *op1, z SET_NODE(opline->op2, op2); } + zend_check_live_ranges(opline); + if (result) { zend_make_tmp_result(result, opline); } @@ -2016,6 +2255,7 @@ static zend_op *zend_delayed_compile_end(uint32_t offset) /* {{{ */ for (i = offset; i < count; ++i) { opline = get_next_op(CG(active_op_array)); memcpy(opline, &oplines[i], sizeof(zend_op)); + zend_check_live_ranges(opline); } CG(delayed_oplines_stack).top = offset; return opline; @@ -2024,6 +2264,11 @@ static zend_op *zend_delayed_compile_end(uint32_t offset) /* {{{ */ static void zend_emit_return_type_check(znode *expr, zend_arg_info *return_info) /* {{{ */ { + /* `return ...;` is illegal in a void function (but `return;` isn't) */ + if (expr && return_info->type_hint == IS_VOID) { + zend_error_noreturn(E_COMPILE_ERROR, "A void function must not return a value"); + } + if (return_info->type_hint != IS_UNDEF) { zend_op *opline = zend_emit_op(NULL, ZEND_VERIFY_RETURN_TYPE, expr, NULL); if (expr && expr->op_type == IS_CONST) { @@ -2040,7 +2285,7 @@ static void zend_emit_return_type_check(znode *expr, zend_arg_info *return_info) } /* }}} */ -void zend_emit_final_return(zval *zv) /* {{{ */ +void zend_emit_final_return(int return_one) /* {{{ */ { znode zn; zend_op *ret; @@ -2051,8 +2296,8 @@ void zend_emit_final_return(zval *zv) /* {{{ */ } zn.op_type = IS_CONST; - if (zv) { - ZVAL_COPY_VALUE(&zn.u.constant, zv); + if (return_one) { + ZVAL_LONG(&zn.u.constant, 1); } else { ZVAL_NULL(&zn.u.constant); } @@ -2171,6 +2416,61 @@ static zend_op *zend_compile_class_ref(znode *result, zend_ast *name_ast, int th } /* }}} */ +static void zend_compile_class_ref_ex(znode *result, zend_ast *name_ast, uint32_t fetch_flags) /* {{{ */ +{ + uint32_t fetch_type; + + if (name_ast->kind != ZEND_AST_ZVAL) { + znode name_node; + + zend_compile_expr(&name_node, name_ast); + + if (name_node.op_type == IS_CONST) { + zend_string *name; + + if (Z_TYPE(name_node.u.constant) != IS_STRING) { + zend_error_noreturn(E_COMPILE_ERROR, "Illegal class name"); + } + + name = Z_STR(name_node.u.constant); + fetch_type = zend_get_class_fetch_type(name); + + if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) { + result->op_type = IS_CONST; + ZVAL_STR(&result->u.constant, zend_resolve_class_name(name, ZEND_NAME_FQ)); + } else { + zend_ensure_valid_class_fetch_type(fetch_type); + result->op_type = IS_UNUSED; + result->u.op.num = fetch_type | fetch_flags; + } + + zend_string_release(name); + } else { + zend_op *opline = zend_emit_op(result, ZEND_FETCH_CLASS, NULL, &name_node); + opline->extended_value = ZEND_FETCH_CLASS_DEFAULT | fetch_flags; + } + return; + } + + /* Fully qualified names are always default refs */ + if (name_ast->attr == ZEND_NAME_FQ) { + result->op_type = IS_CONST; + ZVAL_STR(&result->u.constant, zend_resolve_class_name_ast(name_ast)); + return; + } + + fetch_type = zend_get_class_fetch_type(zend_ast_get_str(name_ast)); + if (ZEND_FETCH_CLASS_DEFAULT == fetch_type) { + result->op_type = IS_CONST; + ZVAL_STR(&result->u.constant, zend_resolve_class_name_ast(name_ast)); + } else { + zend_ensure_valid_class_fetch_type(fetch_type); + result->op_type = IS_UNUSED; + result->u.op.num = fetch_type | fetch_flags; + } +} +/* }}} */ + static int zend_try_compile_cv(znode *result, zend_ast *ast) /* {{{ */ { zend_ast *name_ast = ast->child[0]; @@ -2377,19 +2677,14 @@ zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast, uint32_t znode class_node, prop_node; zend_op *opline; - if (zend_is_const_default_class_ref(class_ast)) { - class_node.op_type = IS_CONST; - ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast)); - } else { - zend_compile_class_ref(&class_node, class_ast, 1); - } + zend_compile_class_ref_ex(&class_node, class_ast, ZEND_FETCH_CLASS_EXCEPTION); zend_compile_expr(&prop_node, prop_ast); if (delayed) { - opline = zend_delayed_emit_op(result, ZEND_FETCH_R, &prop_node, NULL); + opline = zend_delayed_emit_op(result, ZEND_FETCH_STATIC_PROP_R, &prop_node, NULL); } else { - opline = zend_emit_op(result, ZEND_FETCH_R, &prop_node, NULL); + opline = zend_emit_op(result, ZEND_FETCH_STATIC_PROP_R, &prop_node, NULL); } if (opline->op1_type == IS_CONST) { convert_to_string(CT_CONSTANT(opline->op1)); @@ -2402,7 +2697,6 @@ zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast, uint32_t } else { SET_NODE(opline->op2, &class_node); } - opline->extended_value |= ZEND_FETCH_STATIC_MEMBER; return opline; } @@ -2415,9 +2709,8 @@ void zend_compile_static_prop(znode *result, zend_ast *ast, uint32_t type, int d } /* }}} */ -static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_node) /* {{{ */ +static void zend_compile_unkeyed_list_assign(zend_ast_list *list, znode *expr_node) /* {{{ */ { - zend_ast_list *list = zend_ast_get_list(ast); uint32_t i; zend_bool has_elems = 0; @@ -2444,6 +2737,40 @@ static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_n if (!has_elems) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot use empty list"); } +} +/* }}} */ + +static void zend_compile_keyed_list_assign(zend_ast_list *list, znode *expr_node) /* {{{ */ +{ + uint32_t i; + + for (i = 0; i < list->children; ++i) { + zend_ast *pair_ast = list->child[i]; + zend_ast *var_ast = pair_ast->child[0]; + zend_ast *key_ast = pair_ast->child[1]; + znode fetch_result, dim_node; + + zend_compile_expr(&dim_node, key_ast); + + if (expr_node->op_type == IS_CONST) { + Z_TRY_ADDREF(expr_node->u.constant); + } + + zend_emit_op(&fetch_result, ZEND_FETCH_LIST, expr_node, &dim_node); + zend_emit_assign_znode(var_ast, &fetch_result); + } +} +/* }}} */ + +static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_node) /* {{{ */ +{ + zend_ast_list *list = zend_ast_get_list(ast); + + if (list->children > 0 && list->child[0] != NULL && list->child[0]->kind == ZEND_AST_ARRAY_ELEM) { + zend_compile_keyed_list_assign(list, expr_node); + } else { + zend_compile_unkeyed_list_assign(list, expr_node); + } *result = *expr_node; } @@ -2611,7 +2938,7 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */ offset = zend_delayed_compile_begin(); zend_delayed_compile_var(&target_node, target_ast, BP_VAR_W); - zend_delayed_compile_var(&source_node, source_ast, BP_VAR_REF); + zend_delayed_compile_var(&source_node, source_ast, BP_VAR_W); zend_delayed_compile_end(offset); if (source_node.op_type != IS_VAR && zend_is_call(source_ast)) { @@ -2619,9 +2946,6 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */ } opline = zend_emit_op(result, ZEND_ASSIGN_REF, &target_node, &source_node); - if (!result) { - opline->result_type |= EXT_TYPE_UNUSED; - } if (zend_is_call(source_ast)) { opline->extended_value = ZEND_RETURNS_FUNCTION; @@ -2687,7 +3011,6 @@ void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */ uint32_t zend_compile_args(zend_ast *ast, zend_function *fbc) /* {{{ */ { - /* TODO.AST &var error */ zend_ast_list *args = zend_ast_get_list(ast); uint32_t i; zend_bool uses_arg_unpack = 0; @@ -2768,10 +3091,7 @@ uint32_t zend_compile_args(zend_ast *ast, zend_function *fbc) /* {{{ */ } } - opline = get_next_op(CG(active_op_array)); - opline->opcode = opcode; - SET_NODE(opline->op1, &arg_node); - SET_UNUSED(opline->op2); + opline = zend_emit_op(NULL, opcode, &arg_node, NULL); opline->op2.opline_num = arg_num; opline->result.var = (uint32_t)(zend_intptr_t)ZEND_CALL_ARG(NULL, arg_num); @@ -2805,6 +3125,7 @@ ZEND_API zend_uchar zend_get_call_op(zend_uchar init_op, zend_function *fbc) /* } } else { if (zend_execute_ex == execute_ex && + !fbc->common.scope && !(fbc->common.fn_flags & ZEND_ACC_GENERATOR)) { return ZEND_DO_UCALL; } @@ -2874,13 +3195,14 @@ void zend_compile_ns_call(znode *result, znode *name_node, zend_ast *args_ast) / void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_ast) /* {{{ */ { - zend_op *opline = get_next_op(CG(active_op_array)); if (name_node->op_type == IS_CONST && Z_TYPE(name_node->u.constant) == IS_STRING) { const char *colon; zend_string *str = Z_STR(name_node->u.constant); if ((colon = zend_memrchr(ZSTR_VAL(str), ':', ZSTR_LEN(str))) != NULL && colon > ZSTR_VAL(str) && *(colon - 1) == ':') { zend_string *class = zend_string_init(ZSTR_VAL(str), colon - ZSTR_VAL(str) - 1, 0); zend_string *method = zend_string_init(colon + 1, ZSTR_LEN(str) - (colon - ZSTR_VAL(str)) - 1, 0); + zend_op *opline = get_next_op(CG(active_op_array)); + opline->opcode = ZEND_INIT_STATIC_METHOD_CALL; opline->op1_type = IS_CONST; opline->op1.constant = zend_add_class_name_literal(CG(active_op_array), class); @@ -2889,6 +3211,8 @@ void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_a zend_alloc_cache_slot(opline->op2.constant); zval_ptr_dtor(&name_node->u.constant); } else { + zend_op *opline = get_next_op(CG(active_op_array)); + opline->opcode = ZEND_INIT_FCALL_BY_NAME; SET_UNUSED(opline->op1); opline->op2_type = IS_CONST; @@ -2896,9 +3220,7 @@ void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_a zend_alloc_cache_slot(opline->op2.constant); } } else { - opline->opcode = ZEND_INIT_DYNAMIC_CALL; - SET_UNUSED(opline->op1); - SET_NODE(opline->op2, name_node); + zend_emit_op(NULL, ZEND_INIT_DYNAMIC_CALL, NULL, name_node); } zend_compile_call_common(result, args_ast, NULL); @@ -2970,6 +3292,14 @@ int zend_compile_func_defined(znode *result, zend_ast_list *args) /* {{{ */ return FAILURE; } + if (zend_try_ct_eval_const(&result->u.constant, name, 0)) { + zend_string_release(name); + zval_ptr_dtor(&result->u.constant); + ZVAL_TRUE(&result->u.constant); + result->op_type = IS_CONST; + return SUCCESS; + } + opline = zend_emit_op_tmp(result, ZEND_DEFINED, NULL, NULL); opline->op1_type = IS_CONST; LITERAL_STR(opline->op1, name); @@ -2986,6 +3316,46 @@ int zend_compile_func_defined(znode *result, zend_ast_list *args) /* {{{ */ } /* }}} */ +int zend_compile_func_chr(znode *result, zend_ast_list *args) /* {{{ */ +{ + + if (args->children == 1 && + args->child[0]->kind == ZEND_AST_ZVAL && + Z_TYPE_P(zend_ast_get_zval(args->child[0])) == IS_LONG) { + + zend_long c = Z_LVAL_P(zend_ast_get_zval(args->child[0])) & 0xff; + + result->op_type = IS_CONST; + if (CG(one_char_string)[c]) { + ZVAL_INTERNED_STR(&result->u.constant, CG(one_char_string)[c]); + } else { + ZVAL_NEW_STR(&result->u.constant, zend_string_alloc(1, 0)); + Z_STRVAL_P(&result->u.constant)[0] = (char)c; + Z_STRVAL_P(&result->u.constant)[1] = '\0'; + } + return SUCCESS; + } else { + return FAILURE; + } +} +/* }}} */ + +int zend_compile_func_ord(znode *result, zend_ast_list *args) /* {{{ */ +{ + if (args->children == 1 && + args->child[0]->kind == ZEND_AST_ZVAL && + Z_TYPE_P(zend_ast_get_zval(args->child[0])) == IS_STRING) { + + result->op_type = IS_CONST; + ZVAL_LONG(&result->u.constant, (unsigned char)Z_STRVAL_P(zend_ast_get_zval(args->child[0]))[0]); + return SUCCESS; + } else { + return FAILURE; + } +} +/* }}} */ + + static int zend_try_compile_ct_bound_init_user_func(zend_ast *name_ast, uint32_t num_args) /* {{{ */ { zend_string *name, *lcname; @@ -3147,7 +3517,9 @@ static int zend_compile_assert(znode *result, zend_ast_list *args, zend_string * zend_compile_call_common(result, (zend_ast*)args, fbc); - CG(active_op_array)->opcodes[check_op_number].op2.opline_num = get_next_op_number(CG(active_op_array)); + opline = &CG(active_op_array)->opcodes[check_op_number]; + opline->op2.opline_num = get_next_op_number(CG(active_op_array)); + SET_NODE(opline->result, result); } else { if (!fbc) { zend_string_release(name); @@ -3162,7 +3534,7 @@ static int zend_compile_assert(znode *result, zend_ast_list *args, zend_string * } /* }}} */ -int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_list *args, zend_function *fbc) /* {{{ */ +int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_list *args, zend_function *fbc, uint32_t type) /* {{{ */ { if (fbc->internal_function.handler == ZEND_FN(display_disabled_function)) { return FAILURE; @@ -3194,6 +3566,10 @@ int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_l return zend_compile_func_typecheck(result, args, IS_RESOURCE); } else if (zend_string_equals_literal(lcname, "defined")) { return zend_compile_func_defined(result, args); + } else if (zend_string_equals_literal(lcname, "chr") && type == BP_VAR_R) { + return zend_compile_func_chr(result, args); + } else if (zend_string_equals_literal(lcname, "ord") && type == BP_VAR_R) { + return zend_compile_func_ord(result, args); } else if (zend_string_equals_literal(lcname, "call_user_func_array")) { return zend_compile_func_cufa(result, args, lcname); } else if (zend_string_equals_literal(lcname, "call_user_func")) { @@ -3250,7 +3626,7 @@ void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ } if (zend_try_compile_special_func(result, lcname, - zend_ast_get_list(args_ast), fbc) == SUCCESS + zend_ast_get_list(args_ast), fbc, type) == SUCCESS ) { zend_string_release(lcname); zval_ptr_dtor(&name_node.u.constant); @@ -3317,15 +3693,9 @@ void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type) /* {{ znode class_node, method_node; zend_op *opline; - zend_ulong extended_value = 0; + zend_function *fbc = NULL; - if (zend_is_const_default_class_ref(class_ast)) { - class_node.op_type = IS_CONST; - ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast)); - } else { - opline = zend_compile_class_ref(&class_node, class_ast, 1); - extended_value = opline->extended_value; - } + zend_compile_class_ref_ex(&class_node, class_ast, ZEND_FETCH_CLASS_EXCEPTION); zend_compile_expr(&method_node, method_ast); if (method_node.op_type == IS_CONST) { @@ -3341,7 +3711,6 @@ void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type) /* {{ opline = get_next_op(CG(active_op_array)); opline->opcode = ZEND_INIT_STATIC_METHOD_CALL; - opline->extended_value = extended_value; zend_set_class_name_op1(opline, &class_node); @@ -3357,8 +3726,30 @@ void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type) /* {{ } else { SET_NODE(opline->op2, &method_node); } + zend_check_live_ranges(opline); - zend_compile_call_common(result, args_ast, NULL); + /* Check if we already know which method we're calling */ + if (opline->op2_type == IS_CONST) { + zend_class_entry *ce = NULL; + if (opline->op1_type == IS_CONST) { + zend_string *lcname = Z_STR_P(CT_CONSTANT(opline->op1) + 1); + ce = zend_hash_find_ptr(CG(class_table), lcname); + if (!ce && CG(active_class_entry) + && zend_string_equals_ci(CG(active_class_entry)->name, lcname)) { + ce = CG(active_class_entry); + } + } else if (opline->op1_type == IS_UNUSED + && (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF + && zend_is_scope_known()) { + ce = CG(active_class_entry); + } + if (ce) { + zend_string *lcname = Z_STR_P(CT_CONSTANT(opline->op2) + 1); + fbc = zend_hash_find_ptr(&ce->function_table, lcname); + } + } + + zend_compile_call_common(result, args_ast, fbc); } /* }}} */ @@ -3373,10 +3764,7 @@ void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */ zend_op *opline; uint32_t opnum; - if (zend_is_const_default_class_ref(class_ast)) { - class_node.op_type = IS_CONST; - ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast)); - } else if (class_ast->kind == ZEND_AST_CLASS) { + if (class_ast->kind == ZEND_AST_CLASS) { uint32_t dcl_opnum = get_next_op_number(CG(active_op_array)); zend_compile_class_decl(class_ast); /* jump over anon class declaration */ @@ -3386,9 +3774,9 @@ void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */ } class_node.op_type = opline->result_type; class_node.u.op.var = opline->result.var; - opline->op1.opline_num = get_next_op_number(CG(active_op_array)); + opline->extended_value = get_next_op_number(CG(active_op_array)); } else { - zend_compile_class_ref(&class_node, class_ast, 1); + zend_compile_class_ref_ex(&class_node, class_ast, ZEND_FETCH_CLASS_EXCEPTION); } opnum = get_next_op_number(CG(active_op_array)); @@ -3405,7 +3793,8 @@ void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */ zend_compile_call_common(&ctor_result, args_ast, NULL); zend_do_free(&ctor_result); - /* New jumps over ctor call if ctor does not exist */ + /* We save the position of DO_FCALL for convenience in find_live_range(). + * This info is not preserved for runtime. */ opline = &CG(active_op_array)->opcodes[opnum]; opline->op2.opline_num = get_next_op_number(CG(active_op_array)); } @@ -3418,7 +3807,7 @@ void zend_compile_clone(znode *result, zend_ast *ast) /* {{{ */ znode obj_node; zend_compile_expr(&obj_node, obj_ast); - zend_emit_op(result, ZEND_CLONE, &obj_node, NULL); + zend_emit_op_tmp(result, ZEND_CLONE, &obj_node, NULL); } /* }}} */ @@ -3438,19 +3827,27 @@ void zend_compile_global_var(zend_ast *ast) /* {{{ */ zend_op *opline = zend_emit_op(NULL, ZEND_BIND_GLOBAL, &result, &name_node); zend_alloc_cache_slot(opline->op2.constant); } else { - zend_emit_op(&result, ZEND_FETCH_W, &name_node, NULL); + /* name_ast should be evaluated only. FETCH_GLOBAL_LOCK instructs FETCH_W + * to not free the name_node operand, so it can be reused in the following + * ASSIGN_REF, which then frees it. */ + zend_op *opline = zend_emit_op(&result, ZEND_FETCH_W, &name_node, NULL); + opline->extended_value = ZEND_FETCH_GLOBAL_LOCK; - // TODO.AST Avoid double fetch - //opline->extended_value = ZEND_FETCH_GLOBAL_LOCK; + if (name_node.op_type == IS_CONST) { + zend_string_addref(Z_STR(name_node.u.constant)); + } - zend_emit_assign_ref_znode(var_ast, &result); + zend_emit_assign_ref_znode( + zend_ast_create(ZEND_AST_VAR, zend_ast_create_znode(&name_node)), + &result + ); } } /* }}} */ static void zend_compile_static_var_common(zend_ast *var_ast, zval *value, zend_bool by_ref) /* {{{ */ { - znode var_node, result; + znode var_node; zend_op *opline; zend_compile_expr(&var_node, var_ast); @@ -3471,16 +3868,10 @@ static void zend_compile_static_var_common(zend_ast *var_ast, zval *value, zend_ } zend_hash_update(CG(active_op_array)->static_variables, Z_STR(var_node.u.constant), value); - opline = zend_emit_op(&result, by_ref ? ZEND_FETCH_W : ZEND_FETCH_R, &var_node, NULL); - opline->extended_value = ZEND_FETCH_STATIC; - - if (by_ref) { - zend_ast *fetch_ast = zend_ast_create(ZEND_AST_VAR, var_ast); - zend_emit_assign_ref_znode(fetch_ast, &result); - } else { - zend_ast *fetch_ast = zend_ast_create(ZEND_AST_VAR, var_ast); - zend_emit_assign_znode(fetch_ast, &result); - } + 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->extended_value = by_ref; } /* }}} */ @@ -3528,7 +3919,7 @@ void zend_compile_unset(zend_ast *ast) /* {{{ */ return; case ZEND_AST_STATIC_PROP: opline = zend_compile_static_prop_common(NULL, var_ast, BP_VAR_UNSET, 0); - opline->opcode = ZEND_UNSET_VAR; + opline->opcode = ZEND_UNSET_STATIC_PROP; return; EMPTY_SWITCH_DEFAULT_CASE() } @@ -3565,13 +3956,13 @@ static int zend_handle_loops_and_finally_ex(zend_long depth) /* {{{ */ } else { zend_op *opline; - ZEND_ASSERT(loop_var->var_type == IS_VAR || loop_var->var_type == IS_TMP_VAR); + ZEND_ASSERT(loop_var->var_type & (IS_VAR|IS_TMP_VAR)); opline = get_next_op(CG(active_op_array)); opline->opcode = loop_var->opcode; opline->op1_type = loop_var->var_type; opline->op1.var = loop_var->var_num; SET_UNUSED(opline->op2); - opline->op2.num = loop_var->u.brk_cont_offset; + opline->op2.num = loop_var->u.live_range_offset; opline->extended_value = ZEND_FREE_ON_RETURN; depth--; } @@ -3598,7 +3989,7 @@ void zend_compile_return(zend_ast *ast) /* {{{ */ expr_node.op_type = IS_CONST; ZVAL_NULL(&expr_node.u.constant); } else if (by_ref && zend_is_variable(expr_ast) && !zend_is_call(expr_ast)) { - zend_compile_var(&expr_node, expr_ast, BP_VAR_REF); + zend_compile_var(&expr_node, expr_ast, BP_VAR_W); } else { zend_compile_expr(&expr_node, expr_ast); } @@ -3717,14 +4108,14 @@ void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline) /* {{{ */ ZVAL_NULL(label); current = opline->extended_value; - for (; current != dest->brk_cont; current = op_array->brk_cont_array[current].parent) { + for (; current != dest->brk_cont; current = CG(context).brk_cont_array[current].parent) { if (current == -1) { CG(in_compilation) = 1; CG(active_op_array) = op_array; CG(zend_lineno) = opline->lineno; zend_error_noreturn(E_COMPILE_ERROR, "'goto' into loop or switch statement is disallowed"); } - if (op_array->brk_cont_array[current].start >= 0) { + if (CG(context).brk_cont_array[current].start >= 0) { remove_oplines--; } } @@ -3813,7 +4204,7 @@ void zend_compile_while(zend_ast *ast) /* {{{ */ zend_emit_cond_jump(ZEND_JMPNZ, &cond_node, opnum_start); - zend_end_loop(opnum_cond); + zend_end_loop(opnum_cond, NULL); } /* }}} */ @@ -3835,7 +4226,7 @@ void zend_compile_do_while(zend_ast *ast) /* {{{ */ zend_emit_cond_jump(ZEND_JMPNZ, &cond_node, opnum_start); - zend_end_loop(opnum_cond); + zend_end_loop(opnum_cond, NULL); } /* }}} */ @@ -3891,7 +4282,7 @@ void zend_compile_for(zend_ast *ast) /* {{{ */ zend_emit_cond_jump(ZEND_JMPNZ, &result, opnum_start); - zend_end_loop(opnum_loop); + zend_end_loop(opnum_loop, NULL); } /* }}} */ @@ -3935,6 +4326,8 @@ void zend_compile_foreach(zend_ast *ast) /* {{{ */ opnum_reset = get_next_op_number(CG(active_op_array)); opline = zend_emit_op(&reset_node, by_ref ? ZEND_FE_RESET_RW : ZEND_FE_RESET_R, &expr_node, NULL); + zend_begin_loop(ZEND_FE_FREE, &reset_node); + opnum_fetch = get_next_op_number(CG(active_op_array)); opline = zend_emit_op(NULL, by_ref ? ZEND_FE_FETCH_RW : ZEND_FE_FETCH_R, &reset_node, NULL); @@ -3958,8 +4351,6 @@ void zend_compile_foreach(zend_ast *ast) /* {{{ */ zend_emit_assign_znode(key_ast, &key_node); } - zend_begin_loop(ZEND_FE_FREE, &reset_node); - zend_compile_stmt(stmt_ast); zend_emit_jump(opnum_fetch); @@ -3970,9 +4361,9 @@ void zend_compile_foreach(zend_ast *ast) /* {{{ */ opline = &CG(active_op_array)->opcodes[opnum_fetch]; opline->extended_value = get_next_op_number(CG(active_op_array)); - zend_end_loop(opnum_fetch); + zend_end_loop(opnum_fetch, &reset_node); - zend_emit_op(NULL, ZEND_FE_FREE, &reset_node, NULL); + opline = zend_emit_op(NULL, ZEND_FE_FREE, &reset_node, NULL); } /* }}} */ @@ -4092,10 +4483,14 @@ void zend_compile_switch(zend_ast *ast) /* {{{ */ zend_update_jump_target_to_next(opnum_default_jmp); } - zend_end_loop(get_next_op_number(CG(active_op_array))); + zend_end_loop(get_next_op_number(CG(active_op_array)), &expr_node); - if (expr_node.op_type == IS_VAR || expr_node.op_type == IS_TMP_VAR) { - zend_emit_op(NULL, ZEND_FREE, &expr_node, NULL); + if (expr_node.op_type & (IS_VAR|IS_TMP_VAR)) { + /* don't use emit_op() to prevent automatic live-range construction */ + opline = get_next_op(CG(active_op_array)); + opline->opcode = ZEND_FREE; + SET_NODE(opline->op1, &expr_node); + SET_UNUSED(opline->op2); } else if (expr_node.op_type == IS_CONST) { zval_dtor(&expr_node.u.constant); } @@ -4191,7 +4586,9 @@ void zend_compile_try(zend_ast *ast) /* {{{ */ } opline = &CG(active_op_array)->opcodes[opnum_catch]; - opline->extended_value = get_next_op_number(CG(active_op_array)); + if (!is_last_catch) { + opline->extended_value = get_next_op_number(CG(active_op_array)); + } } for (i = 0; i < catches->children; ++i) { @@ -4540,6 +4937,10 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */ zend_compile_typename(type_ast, arg_info); + if (arg_info->type_hint == IS_VOID) { + zend_error_noreturn(E_COMPILE_ERROR, "void cannot be used as a parameter type"); + } + if (type_ast->kind == ZEND_AST_TYPE) { if (arg_info->type_hint == IS_ARRAY) { if (default_ast && !has_null_default @@ -4615,23 +5016,61 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */ } /* }}} */ +static void zend_compile_closure_binding(znode *closure, zend_ast *uses_ast) /* {{{ */ +{ + zend_ast_list *list = zend_ast_get_list(uses_ast); + uint32_t i; + + 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_bool by_ref = var_name_ast->attr; + zend_op *opline; + + if (zend_string_equals_literal(var_name, "this")) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use $this as lexical variable"); + } + + if (zend_is_auto_global(var_name)) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use auto-global as lexical variable"); + } + + 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->extended_value = by_ref; + } +} +/* }}} */ + void zend_compile_closure_uses(zend_ast *ast) /* {{{ */ { + zend_op_array *op_array = CG(active_op_array); zend_ast_list *list = zend_ast_get_list(ast); uint32_t i; for (i = 0; i < list->children; ++i) { zend_ast *var_ast = list->child[i]; - zend_string *name = zend_ast_get_str(var_ast); + zend_string *var_name = zend_ast_get_str(var_ast); zend_bool by_ref = var_ast->attr; zval zv; + ZVAL_NULL(&zv); - if (zend_string_equals_literal(name, "this")) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot use $this as lexical variable"); + if (op_array->static_variables + && zend_hash_exists(op_array->static_variables, var_name)) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot use variable $%s twice", ZSTR_VAL(var_name)); } - ZVAL_NULL(&zv); - Z_CONST_FLAGS(zv) = by_ref ? IS_LEXICAL_REF : IS_LEXICAL_VAR; + { + int i; + for (i = 0; i < op_array->last_var; i++) { + if (zend_string_equals(op_array->vars[i], var_name)) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot use lexical variable $%s as a parameter name", ZSTR_VAL(var_name)); + } + } + } zend_compile_static_var_common(var_ast, &zv, by_ref); } @@ -4811,7 +5250,7 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_ast_decl *decl) /* {{{ */ { zend_ast *params_ast = decl->child[0]; - zend_string *name = decl->name, *lcname; + zend_string *name = decl->name, *lcname, *key; zend_op *opline; op_array->function_name = name = zend_prefix_with_ns(name); @@ -4833,22 +5272,20 @@ static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_as ZEND_AUTOLOAD_FUNC_NAME); } + key = zend_build_runtime_definition_key(lcname, decl->lex_pos); + zend_hash_update_ptr(CG(function_table), key, op_array); + if (op_array->fn_flags & ZEND_ACC_CLOSURE) { opline = zend_emit_op_tmp(result, ZEND_DECLARE_LAMBDA_FUNCTION, NULL, NULL); + opline->op1_type = IS_CONST; + LITERAL_STR(opline->op1, key); } else { opline = get_next_op(CG(active_op_array)); opline->opcode = ZEND_DECLARE_FUNCTION; - opline->op2_type = IS_CONST; - LITERAL_STR(opline->op2, zend_string_copy(lcname)); - } - - { - zend_string *key = zend_build_runtime_definition_key(lcname, decl->lex_pos); - opline->op1_type = IS_CONST; - LITERAL_STR(opline->op1, key); - - zend_hash_update_ptr(CG(function_table), key, op_array); + LITERAL_STR(opline->op1, zend_string_copy(lcname)); + /* RTD key is placed after lcname literal in op1 */ + zend_add_literal_string(CG(active_op_array), &key); } zend_string_release(lcname); @@ -4886,6 +5323,9 @@ void zend_compile_func_decl(znode *result, zend_ast *ast) /* {{{ */ zend_begin_method_decl(op_array, decl->name, has_body); } else { zend_begin_func_decl(result, op_array, decl); + if (uses_ast) { + zend_compile_closure_binding(result, uses_ast); + } } CG(active_op_array) = op_array; @@ -4920,7 +5360,7 @@ void zend_compile_func_decl(znode *result, zend_ast *ast) /* {{{ */ CG(zend_lineno) = decl->end_lineno; zend_do_extended_info(); - zend_emit_final_return(NULL); + zend_emit_final_return(0); pass_two(CG(active_op_array)); zend_oparray_context_end(&orig_oparray_context); @@ -4999,25 +5439,25 @@ void zend_compile_class_const_decl(zend_ast *ast) /* {{{ */ zend_ast *const_ast = list->child[i]; 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 *doc_comment = doc_comment_ast ? zend_string_copy(zend_ast_get_str(doc_comment_ast)) : NULL; zval value_zv; - if (zend_string_equals_literal_ci(name, "class")) { - zend_error(E_COMPILE_ERROR, - "A class constant must not be called 'class'; it is reserved for class name fetching"); + if (UNEXPECTED(ast->attr & (ZEND_ACC_STATIC|ZEND_ACC_ABSTRACT|ZEND_ACC_FINAL))) { + if (ast->attr & ZEND_ACC_STATIC) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'static' as constant modifier"); + } else if (ast->attr & ZEND_ACC_ABSTRACT) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'abstract' as constant modifier"); + } else if (ast->attr & ZEND_ACC_FINAL) { + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'final' as constant modifier"); + } } zend_const_expr_to_zval(&value_zv, value_ast); name = zend_new_interned_string_safe(name); - if (zend_hash_add(&ce->constants_table, name, &value_zv) == NULL) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s", - ZSTR_VAL(ce->name), ZSTR_VAL(name)); - } - - if (Z_CONSTANT(value_zv)) { - ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; - } + zend_declare_class_constant_ex(ce, name, &value_zv, ast->attr, doc_comment); } } /* }}} */ @@ -5274,37 +5714,33 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */ opline = get_next_op(CG(active_op_array)); zend_make_var_result(&declare_node, opline); - // TODO.AST drop this GET_NODE(&FC(implementing_class), opline->result); - opline->op2_type = IS_CONST; - LITERAL_STR(opline->op2, lcname); + opline->op1_type = IS_CONST; + LITERAL_STR(opline->op1, lcname); if (decl->flags & ZEND_ACC_ANON_CLASS) { if (extends_ast) { opline->opcode = ZEND_DECLARE_ANON_INHERITED_CLASS; - opline->extended_value = extends_node.u.op.var; + SET_NODE(opline->op2, &extends_node); } else { opline->opcode = ZEND_DECLARE_ANON_CLASS; } - opline->op1_type = IS_UNUSED; - zend_hash_update_ptr(CG(class_table), lcname, ce); } else { zend_string *key; if (extends_ast) { opline->opcode = ZEND_DECLARE_INHERITED_CLASS; - opline->extended_value = extends_node.u.op.var; + SET_NODE(opline->op2, &extends_node); } else { opline->opcode = ZEND_DECLARE_CLASS; } key = zend_build_runtime_definition_key(lcname, decl->lex_pos); - - opline->op1_type = IS_CONST; - LITERAL_STR(opline->op1, key); + /* RTD key is placed after lcname literal in op1 */ + zend_add_literal_string(CG(active_op_array), &key); zend_hash_update_ptr(CG(class_table), key, ce); } @@ -5801,6 +6237,35 @@ static zend_bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */ } /* }}} */ +ZEND_API zend_bool zend_binary_op_produces_numeric_string_error(uint32_t opcode, zval *op1, zval *op2) /* {{{ */ +{ + if (!(opcode == ZEND_ADD || opcode == ZEND_SUB || opcode == ZEND_MUL || opcode == ZEND_DIV + || opcode == ZEND_POW || opcode == ZEND_MOD || opcode == ZEND_SL || opcode == ZEND_SR + || opcode == ZEND_BW_OR || opcode == ZEND_BW_AND || opcode == ZEND_BW_XOR)) { + return 0; + } + + /* While basic arithmetic operators always produce numeric string errors, + * bitwise operators don't produce errors if both operands are strings */ + if ((opcode == ZEND_BW_OR || opcode == ZEND_BW_AND || opcode == ZEND_BW_XOR) + && Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) { + return 0; + } + + if (Z_TYPE_P(op1) == IS_STRING + && !is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), NULL, NULL, 0)) { + return 1; + } + + if (Z_TYPE_P(op2) == IS_STRING + && !is_numeric_string(Z_STRVAL_P(op2), Z_STRLEN_P(op2), NULL, NULL, 0)) { + return 1; + } + + return 0; +} +/* }}} */ + static inline zend_bool zend_try_ct_eval_binary_op(zval *result, uint32_t opcode, zval *op1, zval *op2) /* {{{ */ { binary_op_type fn = get_binary_op(opcode); @@ -5814,6 +6279,11 @@ static inline zend_bool zend_try_ct_eval_binary_op(zval *result, uint32_t opcode return 0; } + /* don't evaluate numeric string error-producing operations at compile-time */ + if (zend_binary_op_produces_numeric_string_error(opcode, op1, op2)) { + return 0; + } + fn(result, op1, op2); return 1; } @@ -5826,11 +6296,11 @@ static inline void zend_ct_eval_unary_op(zval *result, uint32_t opcode, zval *op } /* }}} */ -static inline void zend_ct_eval_unary_pm(zval *result, zend_ast_kind kind, zval *op) /* {{{ */ +static inline zend_bool zend_try_ct_eval_unary_pm(zval *result, zend_ast_kind kind, zval *op) /* {{{ */ { zval left; ZVAL_LONG(&left, (kind == ZEND_AST_UNARY_PLUS) ? 1 : -1); - mul_function(result, &left, op); + return zend_try_ct_eval_binary_op(result, ZEND_MUL, &left, op); } /* }}} */ @@ -6028,10 +6498,11 @@ void zend_compile_unary_pm(znode *result, zend_ast *ast) /* {{{ */ zend_compile_expr(&expr_node, expr_ast); if (expr_node.op_type == IS_CONST) { - result->op_type = IS_CONST; - zend_ct_eval_unary_pm(&result->u.constant, ast->kind, &expr_node.u.constant); - zval_ptr_dtor(&expr_node.u.constant); - return; + if (zend_try_ct_eval_unary_pm(&result->u.constant, ast->kind, &expr_node.u.constant)) { + result->op_type = IS_CONST; + zval_ptr_dtor(&expr_node.u.constant); + return; + } } lefthand_node.op_type = IS_CONST; @@ -6285,7 +6756,7 @@ void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */ if (value_ast) { if (returns_by_ref && zend_is_variable(value_ast) && !zend_is_call(value_ast)) { - zend_compile_var(&value_node, value_ast, BP_VAR_REF); + zend_compile_var(&value_node, value_ast, BP_VAR_W); } else { zend_compile_expr(&value_node, value_ast); } @@ -6331,13 +6802,8 @@ void zend_compile_instanceof(znode *result, zend_ast *ast) /* {{{ */ "instanceof expects an object instance, constant given"); } - if (zend_is_const_default_class_ref(class_ast)) { - class_node.op_type = IS_CONST; - ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast)); - } else { - opline = zend_compile_class_ref(&class_node, class_ast, 0); - opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD; - } + zend_compile_class_ref_ex(&class_node, class_ast, + ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_EXCEPTION); opline = zend_emit_op_tmp(result, ZEND_INSTANCEOF, &obj_node, NULL); @@ -6409,7 +6875,7 @@ void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */ break; case ZEND_AST_STATIC_PROP: opline = zend_compile_static_prop_common(result, var_ast, BP_VAR_IS, 0); - opline->opcode = ZEND_ISSET_ISEMPTY_VAR; + opline->opcode = ZEND_ISSET_ISEMPTY_STATIC_PROP; break; EMPTY_SWITCH_DEFAULT_CASE() } @@ -6423,10 +6889,9 @@ void zend_compile_silence(znode *result, zend_ast *ast) /* {{{ */ { zend_ast *expr_ast = ast->child[0]; znode silence_node; - uint32_t begin_opline_num, end_opline_num; - zend_brk_cont_element *brk_cont_element; + uint32_t range; - begin_opline_num = get_next_op_number(CG(active_op_array)); + range = zend_start_live_range(CG(active_op_array), get_next_op_number(CG(active_op_array))); zend_emit_op_tmp(&silence_node, ZEND_BEGIN_SILENCE, NULL, NULL); if (expr_ast->kind == ZEND_AST_VAR) { @@ -6437,15 +6902,12 @@ void zend_compile_silence(znode *result, zend_ast *ast) /* {{{ */ zend_compile_expr(result, expr_ast); } - end_opline_num = get_next_op_number(CG(active_op_array)); - zend_emit_op(NULL, ZEND_END_SILENCE, &silence_node, NULL); - /* Store BEGIN_SILENCE/END_SILENCE pair to restore previous * EG(error_reporting) value on exception */ - brk_cont_element = get_next_brk_cont_element(CG(active_op_array)); - brk_cont_element->start = begin_opline_num; - brk_cont_element->cont = brk_cont_element->brk = end_opline_num; - brk_cont_element->parent = -1; + zend_end_live_range(CG(active_op_array), range, get_next_op_number(CG(active_op_array)), + ZEND_LIVE_SILENCE, silence_node.u.op.var); + + zend_emit_op(NULL, ZEND_END_SILENCE, &silence_node, NULL); } /* }}} */ @@ -6589,7 +7051,6 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */ znode class_node, const_node; zend_op *opline; - zend_string *resolved_name; if (zend_try_compile_const_expr_resolve_class_name(&result->u.constant, class_ast, const_ast, 0)) { if (Z_TYPE(result->u.constant) == IS_NULL) { @@ -6605,31 +7066,26 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */ zend_eval_const_expr(&const_ast); if (class_ast->kind == ZEND_AST_ZVAL) { + zend_string *resolved_name; + resolved_name = zend_resolve_class_name_ast(class_ast); if (const_ast->kind == ZEND_AST_ZVAL && zend_try_ct_eval_class_const(&result->u.constant, resolved_name, zend_ast_get_str(const_ast))) { result->op_type = IS_CONST; zend_string_release(resolved_name); return; } + zend_string_release(resolved_name); } if (const_ast->kind == ZEND_AST_ZVAL && zend_string_equals_literal_ci(zend_ast_get_str(const_ast), "class")) { zend_error_noreturn(E_COMPILE_ERROR, "Dynamic class names are not allowed in compile-time ::class fetch"); } - if (zend_is_const_default_class_ref(class_ast)) { - class_node.op_type = IS_CONST; - ZVAL_STR(&class_node.u.constant, resolved_name); - } else { - if (class_ast->kind == ZEND_AST_ZVAL) { - zend_string_release(resolved_name); - } - zend_compile_class_ref(&class_node, class_ast, 1); - } + zend_compile_class_ref_ex(&class_node, class_ast, ZEND_FETCH_CLASS_EXCEPTION); zend_compile_expr(&const_node, const_ast); - opline = zend_emit_op_tmp(result, ZEND_FETCH_CONSTANT, NULL, &const_node); + opline = zend_emit_op_tmp(result, ZEND_FETCH_CLASS_CONSTANT, NULL, &const_node); zend_set_class_name_op1(opline, &class_node); @@ -6771,10 +7227,7 @@ static void zend_compile_encaps_list(znode *result, zend_ast *ast) /* {{{ */ GET_NODE(result, opline->result); } else { uint32_t var; - zend_brk_cont_element *info = get_next_brk_cont_element(CG(active_op_array)); - info->start = rope_init_lineno; - info->parent = CG(context).current_brk_cont; - info->cont = info->brk = opline - CG(active_op_array)->opcodes; + uint32_t range = zend_start_live_range(CG(active_op_array), rope_init_lineno); init_opline->extended_value = j; opline->opcode = ZEND_ROPE_END; @@ -6788,6 +7241,10 @@ static void zend_compile_encaps_list(znode *result, zend_ast *ast) /* {{{ */ get_temporary_variable(CG(active_op_array)); i--; } + + zend_end_live_range(CG(active_op_array), range, opline - CG(active_op_array)->opcodes, + ZEND_LIVE_ROPE, var); + /* Update all the previous opcodes to use the same variable */ while (opline != init_opline) { opline--; @@ -7270,9 +7727,7 @@ void zend_compile_var(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ *result = *zend_ast_get_znode(ast); return; default: - if (type == BP_VAR_W || type == BP_VAR_REF - || type == BP_VAR_RW || type == BP_VAR_UNSET - ) { + if (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot use temporary expression in write context"); } @@ -7382,7 +7837,9 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */ return; } - zend_ct_eval_unary_pm(&result, ast->kind, zend_ast_get_zval(ast->child[0])); + if (!zend_try_ct_eval_unary_pm(&result, ast->kind, zend_ast_get_zval(ast->child[0]))) { + return; + } break; case ZEND_AST_CONDITIONAL: { diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 1bf654eb92..b3ba352df8 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -31,8 +31,6 @@ #include "zend_llist.h" -#define DEBUG_ZEND 0 - #define SET_UNUSED(op) op ## _type = IS_UNUSED #define MAKE_NOP(opline) do { \ @@ -111,18 +109,6 @@ typedef struct _zend_declarables { zend_long ticks; } zend_declarables; -/* Compilation context that is different for each op array. */ -typedef struct _zend_oparray_context { - uint32_t opcodes_size; - int vars_size; - int literals_size; - int current_brk_cont; - int backpatch_count; - int in_finally; - uint32_t fast_call_var; - HashTable *labels; -} zend_oparray_context; - /* Compilation context that is different for each file, but shared between op arrays. */ typedef struct _zend_file_context { zend_declarables declarables; @@ -185,6 +171,32 @@ typedef struct _zend_try_catch_element { uint32_t finally_end; } zend_try_catch_element; +#define ZEND_LIVE_TMPVAR 0 +#define ZEND_LIVE_LOOP 1 +#define ZEND_LIVE_SILENCE 2 +#define ZEND_LIVE_ROPE 3 +#define ZEND_LIVE_MASK 3 + +typedef struct _zend_live_range { + uint32_t var; /* low bits are used for variable type (ZEND_LIVE_* macros) */ + uint32_t start; + uint32_t end; +} zend_live_range; + +/* Compilation context that is different for each op array. */ +typedef struct _zend_oparray_context { + uint32_t opcodes_size; + int vars_size; + int literals_size; + int backpatch_count; + int in_finally; + uint32_t fast_call_var; + int current_brk_cont; + int last_brk_cont; + zend_brk_cont_element *brk_cont_array; + HashTable *labels; +} zend_oparray_context; + /* method flags (types) */ #define ZEND_ACC_STATIC 0x01 #define ZEND_ACC_ABSTRACT 0x02 @@ -296,6 +308,12 @@ typedef struct _zend_property_info { #define OBJ_PROP_TO_NUM(offset) \ ((offset - OBJ_PROP_TO_OFFSET(0)) / sizeof(zval)) +typedef struct _zend_class_constant { + zval value; /* access flags are stored in reserved: zval.u2.access_flags */ + zend_string *doc_comment; + zend_class_entry *ce; +} zend_class_constant; + /* arg_info for internal functions */ typedef struct _zend_internal_arg_info { const char *name; @@ -354,9 +372,9 @@ struct _zend_op_array { uint32_t T; zend_string **vars; - int last_brk_cont; + int last_live_range; int last_try_catch; - zend_brk_cont_element *brk_cont_array; + zend_live_range *live_range; zend_try_catch_element *try_catch_array; /* static variables support */ @@ -450,7 +468,7 @@ struct _zend_execute_data { #define ZEND_CALL_TOP (1 << 1) #define ZEND_CALL_FREE_EXTRA_ARGS (1 << 2) /* equal to IS_TYPE_REFCOUNTED */ #define ZEND_CALL_CTOR (1 << 3) -#define ZEND_CALL_CTOR_RESULT_UNUSED (1 << 4) +/* Unused flag (1 << 4) */ #define ZEND_CALL_CLOSURE (1 << 5) #define ZEND_CALL_RELEASE_THIS (1 << 6) #define ZEND_CALL_ALLOCATED (1 << 7) @@ -514,7 +532,10 @@ struct _zend_execute_data { #define EX_VAR(n) ZEND_CALL_VAR(execute_data, n) #define EX_VAR_NUM(n) ZEND_CALL_VAR_NUM(execute_data, n) -#define EX_VAR_TO_NUM(n) (ZEND_CALL_VAR(NULL, n) - ZEND_CALL_VAR_NUM(NULL, 0)) +#define EX_VAR_TO_NUM(n) ((uint32_t)(ZEND_CALL_VAR(NULL, n) - ZEND_CALL_VAR_NUM(NULL, 0))) + +#define ZEND_OPLINE_TO_OFFSET(opline, target) \ + ((char*)(target) - (char*)(opline)) #define ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline_num) \ ((char*)&(op_array)->opcodes[opline_num] - (char*)(opline)) @@ -531,6 +552,10 @@ struct _zend_execute_data { # define OP_JMP_ADDR(opline, node) \ (node).jmp_addr +# define ZEND_SET_OP_JMP_ADDR(opline, node, val) do { \ + (node).jmp_addr = (val); \ + } while (0) + /* convert jump target from compile-time to run-time */ # define ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, node) do { \ (node).jmp_addr = (op_array)->opcodes + (node).opline_num; \ @@ -547,6 +572,10 @@ struct _zend_execute_data { # define OP_JMP_ADDR(opline, node) \ ZEND_OFFSET_TO_OPLINE(opline, (node).jmp_offset) +# define ZEND_SET_OP_JMP_ADDR(opline, node, val) do { \ + (node).jmp_offset = ZEND_OPLINE_TO_OFFSET(opline, val); \ + } while (0) + /* convert jump target from compile-time to run-time */ # define ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, node) do { \ (node).jmp_offset = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, (node).opline_num); \ @@ -652,8 +681,6 @@ struct _zend_execute_data { #define IS_UNUSED (1<<3) /* Unused variable */ #define IS_CV (1<<4) /* Compiled variable */ -#define EXT_TYPE_UNUSED (1<<5) - #include "zend_globals.h" BEGIN_EXTERN_C() @@ -694,7 +721,7 @@ ZEND_API unary_op_type get_unary_op(int opcode); ZEND_API binary_op_type get_binary_op(int opcode); void zend_stop_lexing(void); -void zend_emit_final_return(zval *zv); +void zend_emit_final_return(int return_one); zend_ast *zend_ast_append_str(zend_ast *left, zend_ast *right); uint32_t zend_add_class_modifier(uint32_t flags, uint32_t new_flag); uint32_t zend_add_member_modifier(uint32_t flags, uint32_t new_flag); @@ -755,7 +782,7 @@ zend_op *get_next_op(zend_op_array *op_array); void init_op(zend_op *op); int get_next_op_number(zend_op_array *op_array); ZEND_API int pass_two(zend_op_array *op_array); -zend_brk_cont_element *get_next_brk_cont_element(zend_op_array *op_array); +zend_brk_cont_element *get_next_brk_cont_element(void); ZEND_API zend_bool zend_is_compiling(void); ZEND_API char *zend_make_compiled_string_description(const char *name); ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers); @@ -802,16 +829,6 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name); #define ZEND_FETCH_CLASS_SILENT 0x0100 #define ZEND_FETCH_CLASS_EXCEPTION 0x0200 -/* variable parsing type (compile-time) */ -#define ZEND_PARSED_MEMBER (1<<0) -#define ZEND_PARSED_METHOD_CALL (1<<1) -#define ZEND_PARSED_STATIC_MEMBER (1<<2) -#define ZEND_PARSED_FUNCTION_CALL (1<<3) -#define ZEND_PARSED_VARIABLE (1<<4) -#define ZEND_PARSED_REFERENCE_VARIABLE (1<<5) -#define ZEND_PARSED_NEW (1<<6) -#define ZEND_PARSED_LIST_EXPR (1<<7) - #define ZEND_PARAM_REF (1<<0) #define ZEND_PARAM_VARIADIC (1<<1) @@ -819,9 +836,6 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name); #define ZEND_NAME_NOT_FQ 1 #define ZEND_NAME_RELATIVE 2 -/* unset types */ -#define ZEND_UNSET_REG 0 - /* var status for backpatching */ #define BP_VAR_R 0 #define BP_VAR_W 1 @@ -829,7 +843,6 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name); #define BP_VAR_IS 3 #define BP_VAR_FUNC_ARG 4 #define BP_VAR_UNSET 5 -#define BP_VAR_REF 6 /* right-hand side of by-ref assignment */ /* Bottom 3 bits are the type, top bits are arg num for BP_VAR_FUNC_ARG */ #define BP_VAR_SHIFT 3 @@ -860,10 +873,7 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name); /* global/local fetches */ #define ZEND_FETCH_GLOBAL 0x00000000 #define ZEND_FETCH_LOCAL 0x10000000 -#define ZEND_FETCH_STATIC 0x20000000 -#define ZEND_FETCH_STATIC_MEMBER 0x30000000 #define ZEND_FETCH_GLOBAL_LOCK 0x40000000 -#define ZEND_FETCH_LEXICAL 0x50000000 #define ZEND_FETCH_TYPE_MASK 0x70000000 @@ -878,8 +888,6 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name); #define ZEND_FREE_ON_RETURN (1<<0) -#define ZEND_MEMBER_FUNC_CALL (1<<0) - #define ZEND_ARG_SEND_BY_REF (1<<0) #define ZEND_ARG_COMPILE_TIME_BOUND (1<<1) #define ZEND_ARG_SEND_FUNCTION (1<<2) @@ -1015,6 +1023,8 @@ END_EXTERN_C() /* The default value for CG(compiler_options) during eval() */ #define ZEND_COMPILE_DEFAULT_FOR_EVAL 0 +ZEND_API zend_bool zend_binary_op_produces_numeric_string_error(uint32_t opcode, zval *op1, zval *op2); + #endif /* ZEND_COMPILE_H */ /* diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index 7e93d93460..e366bae193 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -251,6 +251,18 @@ static zend_constant *zend_get_special_constant(const char *name, size_t name_le } } +ZEND_API int zend_verify_const_access(zend_class_constant *c, zend_class_entry *scope) /* {{{ */ +{ + if (Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PUBLIC) { + return 1; + } else if (Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PRIVATE) { + return (c->ce == scope); + } else { + ZEND_ASSERT(Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PROTECTED); + return zend_check_protected(c->ce, scope); + } +} +/* }}} */ ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len) { @@ -294,7 +306,7 @@ ZEND_API zval *zend_get_constant(zend_string *name) return c ? &c->value : NULL; } -ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, zend_ulong flags) +ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, uint32_t flags) { zend_constant *c; const char *colon; @@ -360,16 +372,23 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, } free_alloca(lcname, use_heap); if (ce) { - ret_constant = zend_hash_find(&ce->constants_table, constant_name); - if (ret_constant == NULL) { + zend_class_constant *c = zend_hash_find_ptr(&ce->constants_table, constant_name); + if (c == NULL) { if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) { zend_throw_error(NULL, "Undefined class constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name)); zend_string_release(class_name); zend_string_free(constant_name); return NULL; } - } else if (Z_ISREF_P(ret_constant)) { - ret_constant = Z_REFVAL_P(ret_constant); + ret_constant = NULL; + } else { + 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(class_name), ZSTR_VAL(constant_name)); + zend_string_release(class_name); + zend_string_free(constant_name); + return NULL; + } + ret_constant = &c->value; } } zend_string_release(class_name); @@ -427,7 +446,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, } } -zend_constant *zend_quick_get_constant(const zval *key, zend_ulong flags) +zend_constant *zend_quick_get_constant(const zval *key, uint32_t flags) { zend_constant *c; diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h index 292d1d305f..cd9a51950a 100644 --- a/Zend/zend_constants.h +++ b/Zend/zend_constants.h @@ -65,9 +65,10 @@ int zend_startup_constants(void); int zend_shutdown_constants(void); void zend_register_standard_constants(void); void clean_non_persistent_constants(void); +ZEND_API int zend_verify_const_access(zend_class_constant *c, zend_class_entry *ce); ZEND_API zval *zend_get_constant(zend_string *name); ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len); -ZEND_API zval *zend_get_constant_ex(zend_string *name, zend_class_entry *scope, zend_ulong flags); +ZEND_API zval *zend_get_constant_ex(zend_string *name, zend_class_entry *scope, uint32_t flags); ZEND_API void zend_register_bool_constant(const char *name, size_t name_len, zend_bool bval, int flags, int module_number); ZEND_API void zend_register_null_constant(const char *name, size_t name_len, int flags, int module_number); ZEND_API void zend_register_long_constant(const char *name, size_t name_len, zend_long lval, int flags, int module_number); @@ -76,7 +77,7 @@ ZEND_API void zend_register_string_constant(const char *name, size_t name_len, c 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); void zend_copy_constants(HashTable *target, HashTable *sourc); -zend_constant *zend_quick_get_constant(const zval *key, zend_ulong flags); +zend_constant *zend_quick_get_constant(const zval *key, uint32_t flags); END_EXTERN_C() #define ZEND_CONSTANT_DTOR free_zend_constant diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index b52dc2362c..21dfdc5146 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -58,17 +58,19 @@ static int zend_implement_throwable(zend_class_entry *interface, zend_class_entr } /* }}} */ -static inline zend_class_entry *i_get_exception_base(zval *object) +static inline zend_class_entry *i_get_exception_base(zval *object) /* {{{ */ { return instanceof_function(Z_OBJCE_P(object), zend_ce_exception) ? zend_ce_exception : zend_ce_error; } +/* }}} */ -ZEND_API zend_class_entry *zend_get_exception_base(zval *object) +ZEND_API zend_class_entry *zend_get_exception_base(zval *object) /* {{{ */ { return i_get_exception_base(object); } +/* }}} */ -void zend_exception_set_previous(zend_object *exception, zend_object *add_previous) +void zend_exception_set_previous(zend_object *exception, zend_object *add_previous) /* {{{ */ { zval *previous, *ancestor, *ex; zval pv, zv, rv; @@ -103,6 +105,7 @@ void zend_exception_set_previous(zend_object *exception, zend_object *add_previo ex = previous; } while (Z_OBJ_P(ex) != add_previous); } +/* }}} */ void zend_exception_save(void) /* {{{ */ { @@ -456,63 +459,6 @@ ZEND_METHOD(error_exception, getSeverity) } \ } while (0) -/* Windows uses VK_ESCAPE instead of \e */ -#ifndef VK_ESCAPE -#define VK_ESCAPE '\e' -#endif - -static size_t compute_escaped_string_len(const char *s, size_t l) { - size_t i, len = l; - for (i = 0; i < l; ++i) { - char c = s[i]; - if (c == '\n' || c == '\r' || c == '\t' || - c == '\f' || c == '\v' || c == '\\' || c == VK_ESCAPE) { - len += 1; - } else if (c < 32 || c > 126) { - len += 3; - } - } - return len; -} - -static void smart_str_append_escaped(smart_str *str, const char *s, size_t l) { - char *res; - size_t i, len = compute_escaped_string_len(s, l); - - smart_str_alloc(str, len, 0); - res = &ZSTR_VAL(str->s)[ZSTR_LEN(str->s)]; - ZSTR_LEN(str->s) += len; - - for (i = 0; i < l; ++i) { - unsigned char c = s[i]; - if (c < 32 || c == '\\' || c > 126) { - *res++ = '\\'; - switch (c) { - case '\n': *res++ = 'n'; break; - case '\r': *res++ = 'r'; break; - case '\t': *res++ = 't'; break; - case '\f': *res++ = 'f'; break; - case '\v': *res++ = 'v'; break; - case '\\': *res++ = '\\'; break; - case VK_ESCAPE: *res++ = 'e'; break; - default: - *res++ = 'x'; - if ((c >> 4) < 10) { - *res++ = (c >> 4) + '0'; - } else { - *res++ = (c >> 4) + 'A' - 10; - } - if ((c & 0xf) < 10) { - *res++ = (c & 0xf) + '0'; - } else { - *res++ = (c & 0xf) + 'A' - 10; - } - } - } else { - *res++ = c; - } - } -} static void _build_trace_args(zval *arg, smart_str *str) /* {{{ */ { @@ -730,7 +676,6 @@ ZEND_METHOD(exception, __toString) fci.size = sizeof(fci); fci.function_table = &Z_OBJCE_P(exception)->function_table; ZVAL_COPY_VALUE(&fci.function_name, &fname); - fci.symbol_table = NULL; fci.object = Z_OBJ_P(exception); fci.retval = &trace; fci.param_count = 0; @@ -979,7 +924,7 @@ static void zend_error_va(int type, const char *file, uint lineno, const char *f } /* }}} */ -static void zend_error_helper(int type, const char *filename, const uint lineno, const char *format, ...) +static void zend_error_helper(int type, const char *filename, const uint lineno, const char *format, ...) /* {{{ */ { va_list va; @@ -987,6 +932,7 @@ static void zend_error_helper(int type, const char *filename, const uint lineno, zend_error_cb(type, filename, lineno, format, va); va_end(va); } +/* }}} */ /* This function doesn't return if it uses E_ERROR */ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* {{{ */ diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 8253fd5d85..5abc2ad75a 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -40,6 +40,7 @@ #include "zend_vm.h" #include "zend_dtrace.h" #include "zend_inheritance.h" +#include "zend_type_info.h" /* Virtual current working directory support */ #include "zend_virtual_cwd.h" @@ -68,7 +69,7 @@ static void zend_extension_statement_handler(const zend_extension *extension, ze static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array); static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array); -#define RETURN_VALUE_USED(opline) (!((opline)->result_type & EXT_TYPE_UNUSED)) +#define RETURN_VALUE_USED(opline) ((opline)->result_type != IS_UNUSED) static ZEND_FUNCTION(pass) { @@ -94,13 +95,10 @@ static const zend_internal_function zend_pass_function = { #define READY_TO_DESTROY(zv) \ (UNEXPECTED(zv) && Z_REFCOUNTED_P(zv) && Z_REFCOUNT_P(zv) == 1) -#define EXTRACT_ZVAL_PTR(zv, check_null) do { \ +#define EXTRACT_ZVAL_PTR(zv) do { \ zval *__zv = (zv); \ if (EXPECTED(Z_TYPE_P(__zv) == IS_INDIRECT)) { \ - if (!(check_null) || \ - EXPECTED(Z_INDIRECT_P(__zv))) { \ - ZVAL_COPY(__zv, Z_INDIRECT_P(__zv)); \ - } \ + ZVAL_COPY(__zv, Z_INDIRECT_P(__zv)); \ } \ } while (0) @@ -119,21 +117,8 @@ static const zend_internal_function zend_pass_function = { zval_ptr_dtor_nogc(should_free); \ } -/* End of zend_execute_locks.h */ - #define CV_DEF_OF(i) (EX(func)->op_array.vars[i]) -#define CTOR_CALL_BIT 0x1 -#define CTOR_USED_BIT 0x2 - -#define IS_CTOR_CALL(ce) (((zend_uintptr_t)(ce)) & CTOR_CALL_BIT) -#define IS_CTOR_USED(ce) (((zend_uintptr_t)(ce)) & CTOR_USED_BIT) - -#define ENCODE_CTOR(ce, used) \ - ((zend_class_entry*)(((zend_uintptr_t)(ce)) | CTOR_CALL_BIT | ((used) ? CTOR_USED_BIT : 0))) -#define DECODE_CTOR(ce) \ - ((zend_class_entry*)(((zend_uintptr_t)(ce)) & ~(CTOR_CALL_BIT|CTOR_USED_BIT))) - #define ZEND_VM_MAIN_STACK_PAGE_SLOTS (16 * 1024) /* should be a power of 2 */ #define ZEND_VM_GENERATOR_STACK_PAGE_SLOTS (256) @@ -150,7 +135,7 @@ static const zend_internal_function zend_pass_function = { static zend_always_inline zend_vm_stack zend_vm_stack_new_page(size_t size, zend_vm_stack prev) { zend_vm_stack page = (zend_vm_stack)emalloc(size); - page->top = ZEND_VM_STACK_ELEMETS(page); + page->top = ZEND_VM_STACK_ELEMENTS(page); page->end = (zval*)((char*)page + size); page->prev = prev; return page; @@ -946,6 +931,24 @@ static ZEND_COLD void zend_verify_internal_return_error(const zend_function *zf, fclass, fsep, fname, need_msg, need_kind, returned_msg, returned_kind); } +static ZEND_COLD void zend_verify_void_return_error(const zend_function *zf, const char *returned_msg, const char *returned_kind) +{ + const char *fname = ZSTR_VAL(zf->common.function_name); + const char *fsep; + const char *fclass; + + if (zf->common.scope) { + fsep = "::"; + fclass = ZSTR_VAL(zf->common.scope->name); + } else { + fsep = ""; + fclass = ""; + } + + zend_type_error("%s%s%s() must not return a value, %s%s returned", + fclass, fsep, fname, returned_msg, returned_kind); +} + #if ZEND_DEBUG static int zend_verify_internal_return_type(zend_function *zf, zval *ret) { @@ -975,6 +978,8 @@ static int zend_verify_internal_return_type(zend_function *zf, zval *ret) } else if (ret_info->type_hint == _IS_BOOL && EXPECTED(Z_TYPE_P(ret) == IS_FALSE || Z_TYPE_P(ret) == IS_TRUE)) { /* pass */ + } else if (ret_info->type_hint == IS_VOID) { + zend_verify_void_return_error(zf, zend_zval_type_name(ret), ""); } else { /* Use strict check to verify return value of internal function */ zend_verify_internal_return_error(zf, "be of the type ", zend_get_type_by_const(ret_info->type_hint), zend_zval_type_name(ret), ""); @@ -1035,6 +1040,12 @@ static zend_always_inline void zend_verify_return_type(zend_function *zf, zval * } else if (ret_info->type_hint == _IS_BOOL && EXPECTED(Z_TYPE_P(ret) == IS_FALSE || Z_TYPE_P(ret) == IS_TRUE)) { /* pass */ + /* There would be a check here for the IS_VOID type hint, which + * would trigger an error because a value had been returned. + * However, zend_compile.c already does a compile-time check + * that bans `return ...;` within a void function. Thus we can skip + * this part of the runtime check for non-internal functions. + */ } else if (UNEXPECTED(!zend_verify_scalar_type_hint(ret_info->type_hint, ret, ZEND_RET_USES_STRICT_TYPES()))) { zend_verify_return_error(zf, "be of the type ", zend_get_type_by_const(ret_info->type_hint), zend_zval_type_name(ret), ""); } @@ -1048,7 +1059,7 @@ static ZEND_COLD int zend_verify_missing_return_type(zend_function *zf, void **c char *need_msg; zend_class_entry *ce; - if (ret_info->type_hint) { + if (ret_info->type_hint && EXPECTED(ret_info->type_hint != IS_VOID)) { if (ret_info->class_name) { if (EXPECTED(*cache_slot)) { ce = (zend_class_entry*)*cache_slot; @@ -1075,164 +1086,6 @@ static ZEND_COLD int zend_verify_missing_return_type(zend_function *zf, void **c return 1; } -static zend_always_inline void zend_assign_to_object(zval *retval, zval *object, uint32_t object_op_type, zval *property_name, uint32_t property_op_type, int value_type, znode_op value_op, const zend_execute_data *execute_data, void **cache_slot) -{ - zend_free_op free_value; - zval *value = get_zval_ptr_r(value_type, value_op, execute_data, &free_value); - zval tmp; - - if (object_op_type != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - do { - if (object_op_type == IS_VAR && UNEXPECTED(object == &EG(error_zval))) { - if (retval) { - ZVAL_NULL(retval); - } - FREE_OP(free_value); - return; - } - 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 (retval) { - ZVAL_NULL(retval); - } - FREE_OP(free_value); - OBJ_RELEASE(obj); - return; - } - Z_DELREF_P(object); - } else { - zend_error(E_WARNING, "Attempt to assign property of non-object"); - if (retval) { - ZVAL_NULL(retval); - } - FREE_OP(free_value); - return; - } - } while (0); - } - - if (property_op_type == IS_CONST && - EXPECTED(Z_OBJCE_P(object) == CACHED_PTR_EX(cache_slot))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR_EX(cache_slot + 1); - zend_object *zobj = Z_OBJ_P(object); - zval *property; - - if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { - property = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property) != IS_UNDEF) { -fast_assign: - value = zend_assign_to_variable(property, value, value_type); - if (retval && EXPECTED(!EG(exception))) { - ZVAL_COPY(retval, value); - } - return; - } - } 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); - if (property) { - goto fast_assign; - } - } - - if (!zobj->ce->__set) { - - if (EXPECTED(zobj->properties == NULL)) { - rebuild_object_properties(zobj); - } - /* separate our value if necessary */ - if (value_type == IS_CONST) { - if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { - ZVAL_COPY_VALUE(&tmp, value); - zval_copy_ctor_func(&tmp); - value = &tmp; - } - } else if (value_type != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (value_type == 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 (value_type == IS_CV && Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, Z_STR_P(property_name), value); - if (retval) { - ZVAL_COPY(retval, value); - } - return; - } - } - } - - if (!Z_OBJ_HT_P(object)->write_property) { - zend_error(E_WARNING, "Attempt to assign property of non-object"); - if (retval) { - ZVAL_NULL(retval); - } - FREE_OP(free_value); - return; - } - - /* separate our value if necessary */ - if (value_type == IS_CONST) { - if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { - ZVAL_COPY_VALUE(&tmp, value); - zval_copy_ctor_func(&tmp); - value = &tmp; - } - } else if (value_type != IS_TMP_VAR) { - ZVAL_DEREF(value); - } - - Z_OBJ_HT_P(object)->write_property(object, property_name, value, cache_slot); - - if (retval && EXPECTED(!EG(exception))) { - ZVAL_COPY(retval, value); - } - if (value_type == IS_CONST) { - zval_ptr_dtor_nogc(value); - } else { - FREE_OP(free_value); - } -} - static zend_never_inline void zend_assign_to_object_dim(zval *retval, zval *object, zval *property_name, int value_type, znode_op value_op, const zend_execute_data *execute_data) { zend_free_op free_value; @@ -1304,8 +1157,11 @@ static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object, zval * static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *value, zval *result) { zend_string *old_str; + zend_uchar c; + size_t string_len; - if (offset < 0) { + if (offset < (zend_long)(-Z_STRLEN_P(str))) { + /* Error on negative offset */ zend_error(E_WARNING, "Illegal string offset: " ZEND_LONG_FMT, offset); zend_string_release(Z_STR_P(str)); if (result) { @@ -1314,8 +1170,35 @@ static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *valu return; } + 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); + + string_len = ZSTR_LEN(tmp); + c = (zend_uchar)ZSTR_VAL(tmp)[0]; + zend_string_release(tmp); + } else { + string_len = Z_STRLEN_P(value); + c = (zend_uchar)Z_STRVAL_P(value)[0]; + } + + if (string_len == 0) { + /* Error on empty input string */ + zend_error(E_WARNING, "Cannot assign an empty string to a string offset"); + zend_string_release(Z_STR_P(str)); + if (result) { + ZVAL_NULL(result); + } + return; + } + + if (offset < 0) { /* Handle negative offset */ + offset += (zend_long)Z_STRLEN_P(str); + } + old_str = Z_STR_P(str); if ((size_t)offset >= Z_STRLEN_P(str)) { + /* Extend string if needed */ zend_long old_len = Z_STRLEN_P(str); Z_STR_P(str) = zend_string_extend(Z_STR_P(str), offset + 1, 0); Z_TYPE_INFO_P(str) = IS_STRING_EX; @@ -1326,23 +1209,11 @@ static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *valu Z_TYPE_INFO_P(str) = IS_STRING_EX; } - if (Z_TYPE_P(value) != IS_STRING) { - zend_string *tmp = zval_get_string(value); - - Z_STRVAL_P(str)[offset] = ZSTR_VAL(tmp)[0]; - zend_string_release(tmp); - } else { - Z_STRVAL_P(str)[offset] = Z_STRVAL_P(value)[0]; - } - /* - * the value of an assignment to a string offset is undefined - T(result->u.var).var = &T->str_offset.str; - */ + Z_STRVAL_P(str)[offset] = c; zend_string_release(old_str); if (result) { - zend_uchar c = (zend_uchar)Z_STRVAL_P(str)[offset]; - + /* Return the new character */ if (CG(one_char_string)[c]) { ZVAL_INTERNED_STR(result, CG(one_char_string)[c]); } else { @@ -1514,15 +1385,6 @@ static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_d if (EXPECTED(fetch_type == ZEND_FETCH_GLOBAL_LOCK) || EXPECTED(fetch_type == ZEND_FETCH_GLOBAL)) { ht = &EG(symbol_table); - } else if (EXPECTED(fetch_type == ZEND_FETCH_STATIC)) { - ZEND_ASSERT(EX(func)->op_array.static_variables != NULL); - ht = EX(func)->op_array.static_variables; - if (GC_REFCOUNT(ht) > 1) { - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_REFCOUNT(ht)--; - } - EX(func)->op_array.static_variables = ht = zend_array_dup(ht); - } } else { ZEND_ASSERT(fetch_type == ZEND_FETCH_LOCAL); if (!EX(symbol_table)) { @@ -1635,7 +1497,7 @@ str_index: default: zend_error(E_WARNING, "Illegal offset type"); retval = (type == BP_VAR_W || type == BP_VAR_RW) ? - &EG(error_zval) : &EG(uninitialized_zval); + NULL : &EG(uninitialized_zval); } } return retval; @@ -1678,6 +1540,120 @@ try_again: return offset; } +static zend_never_inline ZEND_COLD void zend_wrong_string_offset(void) +{ + const char *msg = NULL; + const zend_op *opline = EG(current_execute_data)->opline; + const zend_op *end; + uint32_t var; + + switch (opline->opcode) { + case ZEND_ASSIGN_ADD: + case ZEND_ASSIGN_SUB: + case ZEND_ASSIGN_MUL: + case ZEND_ASSIGN_DIV: + case ZEND_ASSIGN_MOD: + case ZEND_ASSIGN_SL: + case ZEND_ASSIGN_SR: + case ZEND_ASSIGN_CONCAT: + case ZEND_ASSIGN_BW_OR: + case ZEND_ASSIGN_BW_AND: + case ZEND_ASSIGN_BW_XOR: + case ZEND_ASSIGN_POW: + msg = "Cannot use assign-op operators with string offsets"; + break; + case ZEND_FETCH_DIM_W: + case ZEND_FETCH_DIM_RW: + case ZEND_FETCH_DIM_FUNC_ARG: + case ZEND_FETCH_DIM_UNSET: + /* TODO: Encode the "reason" into opline->extended_value??? */ + var = opline->result.var; + opline++; + end = EG(current_execute_data)->func->op_array.opcodes + + EG(current_execute_data)->func->op_array.last; + while (opline < end) { + if (opline->op1_type == IS_VAR && opline->op1.var == var) { + switch (opline->opcode) { + case ZEND_ASSIGN_ADD: + case ZEND_ASSIGN_SUB: + case ZEND_ASSIGN_MUL: + case ZEND_ASSIGN_DIV: + case ZEND_ASSIGN_MOD: + case ZEND_ASSIGN_SL: + case ZEND_ASSIGN_SR: + case ZEND_ASSIGN_CONCAT: + case ZEND_ASSIGN_BW_OR: + case ZEND_ASSIGN_BW_AND: + case ZEND_ASSIGN_BW_XOR: + case ZEND_ASSIGN_POW: + if (opline->extended_value == ZEND_ASSIGN_OBJ) { + msg = "Cannot use string offset as an object"; + } else if (opline->extended_value == ZEND_ASSIGN_DIM) { + msg = "Cannot use string offset as an array"; + } else { + msg = "Cannot use assign-op operators with string offsets"; + } + break; + case ZEND_PRE_INC_OBJ: + case ZEND_PRE_DEC_OBJ: + case ZEND_POST_INC_OBJ: + case ZEND_POST_DEC_OBJ: + case ZEND_PRE_INC: + case ZEND_PRE_DEC: + case ZEND_POST_INC: + case ZEND_POST_DEC: + msg = "Cannot increment/decrement string offsets"; + break; + case ZEND_FETCH_DIM_W: + case ZEND_FETCH_DIM_RW: + case ZEND_FETCH_DIM_FUNC_ARG: + case ZEND_FETCH_DIM_UNSET: + case ZEND_ASSIGN_DIM: + msg = "Cannot use string offset as an array"; + break; + case ZEND_FETCH_OBJ_W: + case ZEND_FETCH_OBJ_RW: + case ZEND_FETCH_OBJ_FUNC_ARG: + case ZEND_FETCH_OBJ_UNSET: + case ZEND_ASSIGN_OBJ: + msg = "Cannot use string offset as an object"; + break; + case ZEND_ASSIGN_REF: + case ZEND_ADD_ARRAY_ELEMENT: + case ZEND_INIT_ARRAY: + msg = "Cannot create references to/from string offsets"; + break; + case ZEND_RETURN_BY_REF: + msg = "Cannot return string offsets by reference"; + break; + case ZEND_UNSET_DIM: + case ZEND_UNSET_OBJ: + msg = "Cannot unset string offsets"; + break; + case ZEND_YIELD: + msg = "Cannot yield string offsets by reference"; + break; + case ZEND_SEND_REF: + case ZEND_SEND_VAR_EX: + msg = "Only variables can be passed by reference"; + break; + EMPTY_SWITCH_DEFAULT_CASE(); + } + break; + } + if (opline->op2_type == IS_VAR && opline->op2.var == var) { + ZEND_ASSERT(opline->opcode == ZEND_ASSIGN_REF); + msg = "Cannot create references to/from string offsets"; + break; + } + } + break; + EMPTY_SWITCH_DEFAULT_CASE(); + } + ZEND_ASSERT(msg != NULL); + zend_throw_error(NULL, msg); +} + static zend_always_inline zend_long zend_fetch_string_offset(zval *container, zval *dim, int type) { zend_long offset = zend_check_string_offset(dim, type); @@ -1704,10 +1680,15 @@ fetch_from_array: retval = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); if (UNEXPECTED(retval == NULL)) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); - retval = &EG(error_zval); + ZVAL_ERROR(result); + return; } } else { retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type); + if (UNEXPECTED(!retval)) { + ZVAL_ERROR(result); + return; + } } ZVAL_INDIRECT(result, retval); return; @@ -1728,15 +1709,15 @@ convert_to_array: if (dim == NULL) { zend_throw_error(NULL, "[] operator not supported for strings"); - ZVAL_INDIRECT(result, &EG(error_zval)); } else { zend_check_string_offset(dim, type); - ZVAL_INDIRECT(result, NULL); /* wrong string offset */ + zend_wrong_string_offset(); } + ZVAL_ERROR(result); } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (!Z_OBJ_HT_P(container)->read_dimension) { zend_throw_error(NULL, "Cannot use object as array"); - retval = &EG(error_zval); + ZVAL_ERROR(result); } else { retval = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result); @@ -1769,25 +1750,25 @@ convert_to_array: ZVAL_INDIRECT(result, retval); } } else { - ZVAL_INDIRECT(result, &EG(error_zval)); + ZVAL_ERROR(result); } } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - if (UNEXPECTED(container == &EG(error_zval))) { - ZVAL_INDIRECT(result, &EG(error_zval)); - } else if (type != BP_VAR_UNSET) { + if (type != BP_VAR_UNSET) { goto convert_to_array; } else { /* for read-mode only */ ZVAL_NULL(result); } + } else if (EXPECTED(Z_ISERROR_P(container))) { + ZVAL_ERROR(result); } else { if (type == BP_VAR_UNSET) { zend_error(E_WARNING, "Cannot unset offset in a non-array variable"); ZVAL_NULL(result); } else { zend_error(E_WARNING, "Cannot use a scalar value as an array"); - ZVAL_INDIRECT(result, &EG(error_zval)); + ZVAL_ERROR(result); } } } @@ -1860,7 +1841,7 @@ try_string_offset: offset = Z_LVAL_P(dim); } - if (UNEXPECTED(offset < 0) || UNEXPECTED(Z_STRLEN_P(container) <= (size_t)offset)) { + if (UNEXPECTED(Z_STRLEN_P(container) < (size_t)((offset < 0) ? -offset : (offset + 1)))) { if (type != BP_VAR_IS) { zend_error(E_NOTICE, "Uninitialized string offset: %pd", offset); ZVAL_EMPTY_STRING(result); @@ -1868,12 +1849,17 @@ try_string_offset: ZVAL_NULL(result); } } else { - zend_uchar c = (zend_uchar)Z_STRVAL_P(container)[offset]; + zend_uchar c; + zend_long real_offset; + + real_offset = (UNEXPECTED(offset < 0)) /* Handle negative offset */ + ? (zend_long)Z_STRLEN_P(container) + offset : offset; + c = (zend_uchar)Z_STRVAL_P(container)[real_offset]; if (CG(one_char_string)[c]) { ZVAL_INTERNED_STR(result, CG(one_char_string)[c]); } else { - ZVAL_NEW_STR(result, zend_string_init(Z_STRVAL_P(container) + offset, 1, 0)); + ZVAL_NEW_STR(result, zend_string_init(Z_STRVAL_P(container) + real_offset, 1, 0)); } } } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { @@ -1916,8 +1902,8 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c { if (container_op_type != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { do { - if (container_op_type == IS_VAR && UNEXPECTED(container == &EG(error_zval))) { - ZVAL_INDIRECT(result, &EG(error_zval)); + if (container_op_type == IS_VAR && UNEXPECTED(Z_ISERROR_P(container))) { + ZVAL_ERROR(result); return; } @@ -1936,7 +1922,7 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c object_init(container); } else { zend_error(E_WARNING, "Attempt to modify property of non-object"); - ZVAL_INDIRECT(result, &EG(error_zval)); + ZVAL_ERROR(result); return; } } while (0); @@ -1979,7 +1965,7 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c } } else { zend_throw_error(NULL, "Cannot access undefined property for object with overloaded property access"); - ZVAL_INDIRECT(result, &EG(error_zval)); + ZVAL_ERROR(result); } } else { ZVAL_INDIRECT(result, ptr); @@ -1993,7 +1979,7 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c } } else { zend_error(E_WARNING, "This object doesn't support property references"); - ZVAL_INDIRECT(result, &EG(error_zval)); + ZVAL_ERROR(result); } } @@ -2368,6 +2354,10 @@ ZEND_API void zend_init_execute_data(zend_execute_data *execute_data, zend_op_ar static zend_always_inline zend_bool zend_is_by_ref_func_arg_fetch(const zend_op *opline, zend_execute_data *call) /* {{{ */ { uint32_t arg_num = opline->extended_value & ZEND_FETCH_ARG_MASK; + + if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { + return QUICK_ARG_SHOULD_BE_SENT_BY_REF(call->func, arg_num); + } return ARG_SHOULD_BE_SENT_BY_REF(call->func, arg_num); } /* }}} */ @@ -2397,7 +2387,7 @@ static zend_execute_data *zend_vm_stack_copy_call_frame(zend_execute_data *call, EG(vm_stack)->prev->top = (zval*)call; /* delete previous stack segment if it becames empty */ - if (UNEXPECTED(EG(vm_stack)->prev->top == ZEND_VM_STACK_ELEMETS(EG(vm_stack)->prev))) { + if (UNEXPECTED(EG(vm_stack)->prev->top == ZEND_VM_STACK_ELEMENTS(EG(vm_stack)->prev))) { zend_vm_stack r = EG(vm_stack)->prev; EG(vm_stack)->prev = r->prev; @@ -2531,9 +2521,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) { - if (!(ZEND_CALL_INFO(call) & ZEND_CALL_CTOR_RESULT_UNUSED)) { - GC_REFCOUNT(Z_OBJ(call->This))--; - } + GC_REFCOUNT(Z_OBJ(call->This))--; if (GC_REFCOUNT(Z_OBJ(call->This)) == 1) { zend_object_store_ctor_failed(Z_OBJ(call->This)); } @@ -2559,30 +2547,29 @@ static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num, { int i; - for (i = 0; i < EX(func)->op_array.last_brk_cont; i++) { - const zend_brk_cont_element *brk_cont = &EX(func)->op_array.brk_cont_array[i]; - if (brk_cont->start < 0) { - continue; - } else if (brk_cont->start > op_num) { + for (i = 0; i < EX(func)->op_array.last_live_range; i++) { + const zend_live_range *range = &EX(func)->op_array.live_range[i]; + if (range->start > op_num) { /* further blocks will not be relevant... */ break; - } else if (op_num < brk_cont->brk) { - if (!catch_op_num || catch_op_num >= brk_cont->brk) { - zend_op *brk_opline = &EX(func)->op_array.opcodes[brk_cont->brk]; - - if (brk_opline->opcode == ZEND_FREE) { - zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var)); - } else if (brk_opline->opcode == ZEND_FE_FREE) { - zval *var = EX_VAR(brk_opline->op1.var); + } else if (op_num < range->end) { + if (!catch_op_num || catch_op_num >= range->end) { + uint32_t kind = range->var & ZEND_LIVE_MASK; + uint32_t var_num = range->var & ~ZEND_LIVE_MASK; + zval *var = EX_VAR(var_num); + + if (kind == ZEND_LIVE_TMPVAR) { + zval_ptr_dtor_nogc(var); + } else if (kind == ZEND_LIVE_LOOP) { 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); - } else if (brk_opline->opcode == ZEND_ROPE_END) { - zend_string **rope = (zend_string **) EX_VAR(brk_opline->op1.var); + } else if (kind == ZEND_LIVE_ROPE) { + zend_string **rope = (zend_string **)var; zend_op *last = EX(func)->op_array.opcodes + op_num; while ((last->opcode != ZEND_ROPE_ADD && last->opcode != ZEND_ROPE_INIT) - || last->result.var != brk_opline->op1.var) { + || last->result.var != var_num) { ZEND_ASSERT(last >= EX(func)->op_array.opcodes); last--; } @@ -2594,10 +2581,10 @@ static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num, zend_string_release(rope[j]); } while (j--); } - } else if (brk_opline->opcode == ZEND_END_SILENCE) { + } else if (kind == ZEND_LIVE_SILENCE) { /* restore previous error_reporting value */ - if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(brk_opline->op1.var)) != 0) { - EG(error_reporting) = Z_LVAL_P(EX_VAR(brk_opline->op1.var)); + if (!EG(error_reporting) && Z_LVAL_P(var) != 0) { + EG(error_reporting) = Z_LVAL_P(var); } } } @@ -2611,6 +2598,20 @@ void zend_cleanup_unfinished_execution(zend_execute_data *execute_data, uint32_t cleanup_live_vars(execute_data, op_num, catch_op_num); } +static void zend_swap_operands(zend_op *op) /* {{{ */ +{ + znode_op tmp; + zend_uchar tmp_type; + + tmp = op->op1; + tmp_type = op->op1_type; + op->op1 = op->op2; + op->op1_type = op->op2_type; + op->op2 = tmp; + op->op2_type = tmp_type; +} +/* }}} */ + #ifdef HAVE_GCC_GLOBAL_REGS # if defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(i386) # define ZEND_VM_FP_GLOBAL_REG "%esi" @@ -2696,10 +2697,34 @@ void zend_cleanup_unfinished_execution(zend_execute_data *execute_data, uint32_t } \ ZEND_VM_CONTINUE(); \ } while (0) +# define ZEND_VM_SMART_BRANCH_JMPZ(_result, _check) do { \ + if ((_check) && UNEXPECTED(EG(exception))) { \ + HANDLE_EXCEPTION(); \ + } \ + if (_result) { \ + ZEND_VM_SET_NEXT_OPCODE(opline + 2); \ + } else { \ + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline + 1, (opline+1)->op2)); \ + } \ + ZEND_VM_CONTINUE(); \ + } while (0) +# define ZEND_VM_SMART_BRANCH_JMPNZ(_result, _check) do { \ + if ((_check) && UNEXPECTED(EG(exception))) { \ + HANDLE_EXCEPTION(); \ + } \ + if (!(_result)) { \ + ZEND_VM_SET_NEXT_OPCODE(opline + 2); \ + } else { \ + ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline + 1, (opline+1)->op2)); \ + } \ + ZEND_VM_CONTINUE(); \ + } while (0) #else # define ZEND_VM_REPEATABLE_OPCODE # define ZEND_VM_REPEAT_OPCODE(_opcode) # define ZEND_VM_SMART_BRANCH(_result, _check) +# define ZEND_VM_SMART_BRANCH_JMPZ(_result, _check) +# define ZEND_VM_SMART_BRANCH_JMPNZ(_result, _check) #endif #ifdef __GNUC__ diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 83336061e4..00c651fdfe 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -145,7 +145,7 @@ struct _zend_vm_stack { #define ZEND_VM_STACK_HEADER_SLOTS \ ((ZEND_MM_ALIGNED_SIZE(sizeof(struct _zend_vm_stack)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval)) - 1) / ZEND_MM_ALIGNED_SIZE(sizeof(zval))) -#define ZEND_VM_STACK_ELEMETS(stack) \ +#define ZEND_VM_STACK_ELEMENTS(stack) \ (((zval*)(stack)) + ZEND_VM_STACK_HEADER_SLOTS) /* diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 650f0a1e52..dc2ce46a7b 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -43,7 +43,7 @@ ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data); ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value); /* true globals */ -ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0}, {{0}}, {0}}, NULL, NULL, NULL, NULL, 0, 0 }; +ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0}, {{0}}, {0}}, NULL, NULL, NULL, 0, 0 }; ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL }; #ifdef ZEND_WIN32 @@ -130,7 +130,7 @@ void init_executor(void) /* {{{ */ zend_init_fpu(); ZVAL_NULL(&EG(uninitialized_zval)); - ZVAL_NULL(&EG(error_zval)); + ZVAL_ERROR(&EG(error_zval)); /* destroys stack frame, therefore makes core dumps worthless */ #if 0&&ZEND_DEBUG original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv); @@ -668,7 +668,7 @@ int call_user_function(HashTable *function_table, zval *object, zval *function_n } /* }}} */ -int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[], int no_separation, zend_array *symbol_table) /* {{{ */ +int _call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[], int no_separation) /* {{{ */ { zend_fcall_info fci; @@ -680,7 +680,6 @@ int call_user_function_ex(HashTable *function_table, zval *object, zval *functio fci.param_count = param_count; fci.params = params; fci.no_separation = (zend_bool) no_separation; - fci.symbol_table = symbol_table; return zend_call_function(&fci, NULL); } @@ -851,13 +850,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / ZEND_ADD_CALL_FLAG(call, ZEND_CALL_CLOSURE); } - /* PHP-7 doesn't support symbol_table substitution for functions */ - ZEND_ASSERT(fci->symbol_table == NULL); - if (func->type == ZEND_USER_FUNCTION) { int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0; EG(scope) = func->common.scope; - call->symbol_table = fci->symbol_table; + call->symbol_table = NULL; if (EXPECTED((func->op_array.fn_flags & ZEND_ACC_GENERATOR) == 0)) { zend_init_execute_data(call, &func->op_array, fci->retval); zend_execute_ex(call); @@ -1027,7 +1023,6 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k fcall_info.size = sizeof(fcall_info); fcall_info.function_table = EG(function_table); ZVAL_STR_COPY(&fcall_info.function_name, EG(autoload_func)->common.function_name); - fcall_info.symbol_table = NULL; fcall_info.retval = &local_retval; fcall_info.param_count = 1; fcall_info.params = args; diff --git a/Zend/zend_extensions.h b/Zend/zend_extensions.h index 06cb43d2ed..a0e570a7ae 100644 --- a/Zend/zend_extensions.h +++ b/Zend/zend_extensions.h @@ -25,10 +25,28 @@ #include "zend_compile.h" #include "zend_build.h" +/* +The constants below are derived from ext/opcache/ZendAccelerator.h + +You can use the following macro to check the extension API version for compatibilities: + +#define ZEND_EXTENSION_API_NO_5_0_X 220040412 +#define ZEND_EXTENSION_API_NO_5_1_X 220051025 +#define ZEND_EXTENSION_API_NO_5_2_X 220060519 +#define ZEND_EXTENSION_API_NO_5_3_X 220090626 +#define ZEND_EXTENSION_API_NO_5_4_X 220100525 +#define ZEND_EXTENSION_API_NO_5_5_X 220121212 +#define ZEND_EXTENSION_API_NO_5_6_X 220131226 +#define ZEND_EXTENSION_API_NO_7_0_X 320151012 + +#if ZEND_EXTENSION_API_NO < ZEND_EXTENSION_API_NO_5_5_X + // do something for php versions lower than 5.5.x +#endif +*/ + /* The first number is the engine version and the rest is the date (YYYYMMDD). - * This way engine 2/3 API no. is always greater than engine 1 API no.. - */ -#define ZEND_EXTENSION_API_NO 320151012 + * This way engine 2/3 API no. is always greater than engine 1 API no.. */ +#define ZEND_EXTENSION_API_NO 320160303 typedef struct _zend_extension_version_info { int zend_extension_api_no; diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 646e46b676..5a3e84ccd1 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -93,6 +93,12 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished OBJ_RELEASE((zend_object *) EX(func)->common.prototype); } + /* Free GC buffer. GC for closed generators doesn't need an allocated buffer */ + if (generator->gc_buffer) { + efree(generator->gc_buffer); + generator->gc_buffer = NULL; + } + efree(generator->stack); generator->execute_data = NULL; } @@ -190,12 +196,99 @@ static void zend_generator_free_storage(zend_object *object) /* {{{ */ } /* }}} */ +static uint32_t calc_gc_buffer_size(zend_generator *generator) /* {{{ */ +{ + uint32_t size = 4; /* value, key, retval, values */ + if (generator->execute_data) { + zend_execute_data *execute_data = generator->execute_data; + zend_op_array *op_array = &EX(func)->op_array; + + /* Compiled variables */ + if (!execute_data->symbol_table) { + size += op_array->last_var; + } + /* Extra args */ + if (EX_CALL_INFO() & ZEND_CALL_FREE_EXTRA_ARGS) { + size += EX_NUM_ARGS() - op_array->num_args; + } + size += Z_OBJ(execute_data->This) != NULL; /* $this */ + size += (EX_CALL_INFO() & ZEND_CALL_CLOSURE) != 0; /* Closure object */ + + /* Yield from root references */ + if (generator->node.children == 0) { + zend_generator *root = generator->node.ptr.root; + while (root != generator) { + size++; + root = zend_generator_get_child(&root->node, generator); + } + } + } + return size; +} +/* }}} */ + static HashTable *zend_generator_get_gc(zval *object, zval **table, int *n) /* {{{ */ { zend_generator *generator = (zend_generator*) Z_OBJ_P(object); - *table = &generator->value; - *n = 3; - return NULL; + zend_execute_data *execute_data = generator->execute_data; + zend_op_array *op_array; + zval *gc_buffer; + uint32_t gc_buffer_size; + + if (!execute_data) { + /* If the generator has been closed, it can only hold on to three values: The value, key + * and retval. These three zvals are stored sequentially starting at &generator->value. */ + *table = &generator->value; + *n = 3; + return NULL; + } + + op_array = &EX(func)->op_array; + gc_buffer_size = calc_gc_buffer_size(generator); + if (generator->gc_buffer_size < gc_buffer_size) { + generator->gc_buffer = safe_erealloc(generator->gc_buffer, sizeof(zval), gc_buffer_size, 0); + generator->gc_buffer_size = gc_buffer_size; + } + + *n = gc_buffer_size; + *table = gc_buffer = generator->gc_buffer; + + ZVAL_COPY_VALUE(gc_buffer++, &generator->value); + ZVAL_COPY_VALUE(gc_buffer++, &generator->key); + ZVAL_COPY_VALUE(gc_buffer++, &generator->retval); + ZVAL_COPY_VALUE(gc_buffer++, &generator->values); + + if (!execute_data->symbol_table) { + uint32_t i, num_cvs = EX(func)->op_array.last_var; + for (i = 0; i < num_cvs; i++) { + ZVAL_COPY_VALUE(gc_buffer++, EX_VAR_NUM(i)); + } + } + + if (EX_CALL_INFO() & ZEND_CALL_FREE_EXTRA_ARGS) { + zval *zv = EX_VAR_NUM(op_array->last_var + op_array->T); + zval *end = zv + (EX_NUM_ARGS() - op_array->num_args); + while (zv != end) { + ZVAL_COPY_VALUE(gc_buffer++, zv++); + } + } + + if (Z_OBJ(execute_data->This)) { + ZVAL_OBJ(gc_buffer++, Z_OBJ(execute_data->This)); + } + if (EX_CALL_INFO() & ZEND_CALL_CLOSURE) { + ZVAL_OBJ(gc_buffer++, (zend_object *) EX(func)->common.prototype); + } + + if (generator->node.children == 0) { + zend_generator *child = generator, *root = generator->node.ptr.root; + while (root != child) { + ZVAL_OBJ(gc_buffer++, &child->std); + child = child->node.parent; + } + } + + return execute_data->symbol_table; } /* }}} */ @@ -293,6 +386,8 @@ ZEND_API zend_execute_data *zend_generator_check_placeholder_frame(zend_execute_ static void zend_generator_throw_exception(zend_generator *generator, zval *exception) { + zend_execute_data *original_execute_data = EG(current_execute_data); + /* if we don't stop an array/iterator yield from, the exception will only reach the generator after the values were all iterated over */ if (UNEXPECTED(Z_TYPE(generator->values) != IS_UNDEF)) { zval_ptr_dtor(&generator->values); @@ -301,7 +396,6 @@ static void zend_generator_throw_exception(zend_generator *generator, zval *exce /* Throw the exception in the context of the generator. Decrementing the opline * to pretend the exception happened during the YIELD opcode. */ - zend_execute_data *original_execute_data = EG(current_execute_data); EG(current_execute_data) = generator->execute_data; generator->execute_data->opline--; if (exception) { diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h index 26ee646b65..95c5147a93 100644 --- a/Zend/zend_generators.h +++ b/Zend/zend_generators.h @@ -82,7 +82,7 @@ struct _zend_generator { * by-value foreach. */ zval values; - /* Node of waiting generators when multiple "yield *" expressions + /* Node of waiting generators when multiple "yield from" expressions * are nested. */ zend_generator_node node; @@ -91,6 +91,9 @@ struct _zend_generator { /* ZEND_GENERATOR_* flags */ zend_uchar flags; + + zval *gc_buffer; + uint32_t gc_buffer_size; }; static const zend_uchar ZEND_GENERATOR_CURRENTLY_RUNNING = 0x1; diff --git a/Zend/zend_globals_macros.h b/Zend/zend_globals_macros.h index d2baef3555..c0a9efbfbf 100644 --- a/Zend/zend_globals_macros.h +++ b/Zend/zend_globals_macros.h @@ -68,34 +68,6 @@ extern ZEND_API zend_ini_scanner_globals ini_scanner_globals; END_EXTERN_C() -/* For limited downwards source compatibility */ -#define CLS_FETCH() -#define ELS_FETCH() -#define ALS_FETCH() -#define PLS_FETCH() -#define SLS_FETCH() -#define CLS_D -#define ELS_D -#define ALS_D -#define PLS_D -#define SLS_D -#define CLS_DC -#define ELS_DC -#define ALS_DC -#define PLS_DC -#define SLS_DC -#define CLS_C -#define ELS_C -#define ALS_C -#define PLS_C -#define SLS_C -#define CLS_CC -#define ELS_CC -#define ALS_CC -#define PLS_CC -#define SLS_CC - - #endif /* ZEND_GLOBALS_MACROS_H */ /* diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index f4c2c30fbc..f18ce5c058 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -248,7 +248,7 @@ END_EXTERN_C() static zend_always_inline int _zend_handle_numeric_str(const char *key, size_t length, zend_ulong *idx) { - register const char *tmp = key; + const char *tmp = key; if (*tmp > '9') { return 0; diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 55a9fdc909..1243552d59 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -546,17 +546,17 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function * zend_error_noreturn(E_COMPILE_ERROR, "Cannot make non abstract method %s::%s() abstract in class %s", ZEND_FN_SCOPE_NAME(parent), ZSTR_VAL(child->common.function_name), ZEND_FN_SCOPE_NAME(child)); } + /* Prevent derived classes from restricting access that was available in parent classes */ + if (UNEXPECTED((child_flags & ZEND_ACC_PPP_MASK) > (parent_flags & ZEND_ACC_PPP_MASK))) { + zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::%s() must be %s (as in class %s)%s", ZEND_FN_SCOPE_NAME(child), ZSTR_VAL(child->common.function_name), zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); + } + + if (((child_flags & ZEND_ACC_PPP_MASK) < (parent_flags & ZEND_ACC_PPP_MASK)) + && ((parent_flags & ZEND_ACC_PPP_MASK) & ZEND_ACC_PRIVATE)) { + child->common.fn_flags |= ZEND_ACC_CHANGED; + } if (parent_flags & ZEND_ACC_CHANGED) { child->common.fn_flags |= ZEND_ACC_CHANGED; - } else { - /* Prevent derived classes from restricting access that was available in parent classes - */ - if (UNEXPECTED((child_flags & ZEND_ACC_PPP_MASK) > (parent_flags & ZEND_ACC_PPP_MASK))) { - zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::%s() must be %s (as in class %s)%s", ZEND_FN_SCOPE_NAME(child), ZSTR_VAL(child->common.function_name), zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); - } else if (((child_flags & ZEND_ACC_PPP_MASK) < (parent_flags & ZEND_ACC_PPP_MASK)) - && ((parent_flags & ZEND_ACC_PPP_MASK) & ZEND_ACC_PRIVATE)) { - child->common.fn_flags |= ZEND_ACC_CHANGED; - } } if (parent_flags & ZEND_ACC_PRIVATE) { @@ -718,21 +718,29 @@ ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_ } /* }}} */ -static void do_inherit_class_constant(zend_string *name, zval *zv, zend_class_entry *ce, zend_class_entry *parent_ce) /* {{{ */ +static void do_inherit_class_constant(zend_string *name, zend_class_constant *parent_const, zend_class_entry *ce) /* {{{ */ { - if (!zend_hash_exists(&ce->constants_table, name)) { - if (!Z_ISREF_P(zv)) { - if (parent_ce->type == ZEND_INTERNAL_CLASS) { - ZVAL_NEW_PERSISTENT_REF(zv, zv); - } else { - ZVAL_NEW_REF(zv, zv); - } + zend_class_constant *c = zend_hash_find_ptr(&ce->constants_table, name); + + if (c != NULL) { + 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"); } - if (Z_CONSTANT_P(Z_REFVAL_P(zv))) { + } else if (!(Z_ACCESS_FLAGS(parent_const->value) & ZEND_ACC_PRIVATE)) { + if (Z_CONSTANT(parent_const->value)) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } - Z_ADDREF_P(zv); - _zend_hash_append(&ce->constants_table, name, zv); + 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; + } + _zend_hash_append_ptr(&ce->constants_table, name, c); } } /* }}} */ @@ -742,7 +750,6 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent zend_property_info *property_info; zend_function *func; zend_string *key; - zval *zv; if (UNEXPECTED(ce->ce_flags & ZEND_ACC_INTERFACE)) { /* Interface can only inherit other interfaces */ @@ -879,12 +886,14 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent } if (zend_hash_num_elements(&parent_ce->constants_table)) { + zend_class_constant *c; + zend_hash_extend(&ce->constants_table, zend_hash_num_elements(&ce->constants_table) + zend_hash_num_elements(&parent_ce->constants_table), 0); - ZEND_HASH_FOREACH_STR_KEY_VAL(&parent_ce->constants_table, key, zv) { - do_inherit_class_constant(key, zv, ce, parent_ce); + ZEND_HASH_FOREACH_STR_KEY_PTR(&parent_ce->constants_table, key, c) { + do_inherit_class_constant(key, c, ce); } ZEND_HASH_FOREACH_END(); } @@ -914,14 +923,12 @@ 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, zval *parent_constant, zend_string *name, const zend_class_entry *iface) /* {{{ */ +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 *old_constant; + zend_class_constant *old_constant; - if ((old_constant = zend_hash_find(child_constants_table, name)) != NULL) { - if (!Z_ISREF_P(old_constant) || - !Z_ISREF_P(parent_constant) || - Z_REFVAL_P(old_constant) != Z_REFVAL_P(parent_constant)) { + if ((old_constant = zend_hash_find_ptr(child_constants_table, name)) != NULL) { + 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)); } return 0; @@ -930,21 +937,23 @@ static zend_bool do_inherit_constant_check(HashTable *child_constants_table, zva } /* }}} */ -static void do_inherit_iface_constant(zend_string *name, zval *zv, zend_class_entry *ce, zend_class_entry *iface) /* {{{ */ +static void do_inherit_iface_constant(zend_string *name, zend_class_constant *c, zend_class_entry *ce, zend_class_entry *iface) /* {{{ */ { - if (do_inherit_constant_check(&ce->constants_table, zv, name, iface)) { - if (!Z_ISREF_P(zv)) { - if (iface->type == ZEND_INTERNAL_CLASS) { - ZVAL_NEW_PERSISTENT_REF(zv, zv); - } else { - ZVAL_NEW_REF(zv, zv); - } - } - Z_ADDREF_P(zv); - if (Z_CONSTANT_P(Z_REFVAL_P(zv))) { + if (do_inherit_constant_check(&ce->constants_table, c, name, iface)) { + zend_class_constant *ct; + if (Z_CONSTANT(c->value)) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } - zend_hash_update(&ce->constants_table, name, zv); + 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; + } + zend_hash_update_ptr(&ce->constants_table, name, ct); } } /* }}} */ @@ -956,7 +965,7 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry uint32_t parent_iface_num = ce->parent ? ce->parent->num_interfaces : 0; zend_function *func; zend_string *key; - zval *zv; + zend_class_constant *c; for (i = 0; i < ce->num_interfaces; i++) { if (ce->interfaces[i] == NULL) { @@ -972,8 +981,8 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry } if (ignore) { /* Check for attempt to redeclare interface constants */ - ZEND_HASH_FOREACH_STR_KEY_VAL(&ce->constants_table, key, zv) { - do_inherit_constant_check(&iface->constants_table, zv, key, iface); + ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) { + do_inherit_constant_check(&iface->constants_table, c, key, iface); } ZEND_HASH_FOREACH_END(); } else { if (ce->num_interfaces >= current_iface_num) { @@ -985,8 +994,8 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry } ce->interfaces[ce->num_interfaces++] = iface; - ZEND_HASH_FOREACH_STR_KEY_VAL(&iface->constants_table, key, zv) { - do_inherit_iface_constant(key, zv, ce, iface); + ZEND_HASH_FOREACH_STR_KEY_PTR(&iface->constants_table, key, c) { + do_inherit_iface_constant(key, c, ce, iface); } ZEND_HASH_FOREACH_END(); ZEND_HASH_FOREACH_STR_KEY_PTR(&iface->function_table, key, func) { diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index 6ad8966870..c7d225704f 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -55,7 +55,6 @@ ZEND_API zval* zend_call_method(zval *object, zend_class_entry *obj_ce, zend_fun fci.param_count = param_count; fci.params = params; fci.no_separation = 1; - fci.symbol_table = NULL; if (!fn_proxy && !obj_ce) { /* no interest in caching and no information already present that is diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 804ed37473..0ec991e908 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -241,7 +241,8 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type <ast> exit_expr scalar backticks_expr lexical_var function_call member_name property_name %type <ast> variable_class_name dereferencable_scalar constant dereferencable %type <ast> callable_expr callable_variable static_member new_variable -%type <ast> assignment_list_element array_pair encaps_var encaps_var_offset isset_variables +%type <ast> unkeyed_assignment_list_element keyed_assignment_list_element array_pair +%type <ast> encaps_var encaps_var_offset isset_variables %type <ast> top_statement_list use_declarations const_list inner_statement_list if_stmt %type <ast> alt_if_stmt for_exprs switch_case_list global_var_list static_var_list %type <ast> echo_expr_list unset_variables catch_list parameter_list class_statement_list @@ -250,7 +251,8 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type <ast> class_const_list class_const_decl name_list trait_adaptations method_body non_empty_for_exprs %type <ast> ctor_arguments alt_if_stmt_without_else trait_adaptation_list lexical_vars %type <ast> lexical_var_list encaps_list array_pair_list non_empty_array_pair_list -%type <ast> assignment_list isset_variable type return_type +%type <ast> assignment_list unkeyed_assignment_list keyed_assignment_list +%type <ast> isset_variable type return_type %type <ast> identifier %type <num> returns_ref function is_reference is_variadic variable_modifiers @@ -701,8 +703,8 @@ class_statement_list: class_statement: variable_modifiers property_list ';' { $$ = $2; $$->attr = $1; } - | T_CONST class_const_list ';' - { $$ = $2; RESET_DOC_COMMENT(); } + | method_modifiers T_CONST class_const_list ';' + { $$ = $3; $$->attr = $1; } | T_USE name_list trait_adaptations { $$ = zend_ast_create(ZEND_AST_USE_TRAIT, $2, $3); } | method_modifiers function returns_ref identifier backup_doc_comment '(' parameter_list ')' @@ -810,11 +812,11 @@ class_const_list: ; class_const_decl: - identifier '=' expr { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3); } + identifier '=' expr backup_doc_comment { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL)); } ; const_decl: - T_STRING '=' expr { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3); } + T_STRING '=' expr backup_doc_comment { $$ = zend_ast_create(ZEND_AST_CONST_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL)); } ; echo_expr_list: @@ -1170,18 +1172,39 @@ property_name: ; assignment_list: - assignment_list ',' assignment_list_element + unkeyed_assignment_list + { $$ = $1; } + | keyed_assignment_list possible_comma + { $$ = $1; } +; + +unkeyed_assignment_list: + unkeyed_assignment_list ',' unkeyed_assignment_list_element { $$ = zend_ast_list_add($1, $3); } - | assignment_list_element + | unkeyed_assignment_list_element { $$ = zend_ast_create_list(1, ZEND_AST_LIST, $1); } ; -assignment_list_element: +unkeyed_assignment_list_element: variable { $$ = $1; } | T_LIST '(' assignment_list ')' { $$ = $3; } | /* empty */ { $$ = NULL; } ; +keyed_assignment_list: + keyed_assignment_list ',' keyed_assignment_list_element + { $$ = zend_ast_list_add($1, $3); } + | keyed_assignment_list_element + { $$ = zend_ast_create_list(1, ZEND_AST_LIST, $1); } +; + +keyed_assignment_list_element: + expr T_DOUBLE_ARROW variable + { $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, $1); } + | expr T_DOUBLE_ARROW T_LIST '(' assignment_list ')' + { $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $5, $1); } +; + array_pair_list: /* empty */ { $$ = zend_ast_create_list(0, ZEND_AST_ARRAY); } diff --git a/Zend/zend_language_scanner.c b/Zend/zend_language_scanner.c index 9df9828eb4..7809f95f11 100644 --- a/Zend/zend_language_scanner.c +++ b/Zend/zend_language_scanner.c @@ -570,6 +570,48 @@ ZEND_API int open_file_for_scanning(zend_file_handle *file_handle) } END_EXTERN_C() +static zend_op_array *zend_compile(int type) +{ + zend_op_array *op_array = NULL; + zend_bool original_in_compilation = CG(in_compilation); + + CG(in_compilation) = 1; + CG(ast) = NULL; + CG(ast_arena) = zend_arena_create(1024 * 32); + + if (!zendparse()) { + zend_file_context original_file_context; + zend_oparray_context original_oparray_context; + zend_op_array *original_active_op_array = CG(active_op_array); + + op_array = emalloc(sizeof(zend_op_array)); + init_op_array(op_array, type, INITIAL_OP_ARRAY_SIZE); + CG(active_op_array) = op_array; + + if (zend_ast_process) { + zend_ast_process(CG(ast)); + } + + zend_file_context_begin(&original_file_context); + zend_oparray_context_begin(&original_oparray_context); + zend_compile_top_stmt(CG(ast)); + zend_emit_final_return(type == ZEND_USER_FUNCTION); + op_array->line_start = 1; + op_array->line_end = CG(zend_lineno); + pass_two(op_array); + zend_oparray_context_end(&original_oparray_context); + zend_file_context_end(&original_file_context); + + CG(active_op_array) = original_active_op_array; + } + + zend_ast_destroy(CG(ast)); + zend_arena_destroy(CG(ast_arena)); + + CG(in_compilation) = original_in_compilation; + + return op_array; +} ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type) { @@ -585,41 +627,7 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type) zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename); } } else { - zend_bool original_in_compilation = CG(in_compilation); - CG(in_compilation) = 1; - - CG(ast) = NULL; - CG(ast_arena) = zend_arena_create(1024 * 32); - if (!zendparse()) { - zval retval_zv; - zend_file_context original_file_context; - zend_oparray_context original_oparray_context; - zend_op_array *original_active_op_array = CG(active_op_array); - op_array = emalloc(sizeof(zend_op_array)); - init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE); - CG(active_op_array) = op_array; - ZVAL_LONG(&retval_zv, 1); - - if (zend_ast_process) { - zend_ast_process(CG(ast)); - } - - zend_file_context_begin(&original_file_context); - zend_oparray_context_begin(&original_oparray_context); - zend_compile_top_stmt(CG(ast)); - zend_emit_final_return(&retval_zv); - op_array->line_start = 1; - op_array->line_end = CG(zend_lineno); - pass_two(op_array); - zend_oparray_context_end(&original_oparray_context); - zend_file_context_end(&original_file_context); - - CG(active_op_array) = original_active_op_array; - } - - zend_ast_destroy(CG(ast)); - zend_arena_destroy(CG(ast_arena)); - CG(in_compilation) = original_in_compilation; + op_array = zend_compile(ZEND_USER_FUNCTION); } zend_restore_lexical_state(&original_lex_state); @@ -734,13 +742,11 @@ ZEND_API size_t zend_get_scanned_file_offset(void) return offset; } - zend_op_array *compile_string(zval *source_string, char *filename) { zend_lex_state original_lex_state; zend_op_array *op_array = NULL; zval tmp; - zend_bool original_in_compilation = CG(in_compilation); if (Z_STRLEN_P(source_string)==0) { return NULL; @@ -750,45 +756,15 @@ zend_op_array *compile_string(zval *source_string, char *filename) convert_to_string(&tmp); source_string = &tmp; - CG(in_compilation) = 1; zend_save_lexical_state(&original_lex_state); if (zend_prepare_string_for_scanning(source_string, filename) == SUCCESS) { - CG(ast) = NULL; - CG(ast_arena) = zend_arena_create(1024 * 32); BEGIN(ST_IN_SCRIPTING); - - if (!zendparse()) { - zend_file_context original_file_context; - zend_oparray_context original_oparray_context; - zend_op_array *original_active_op_array = CG(active_op_array); - op_array = emalloc(sizeof(zend_op_array)); - init_op_array(op_array, ZEND_EVAL_CODE, INITIAL_OP_ARRAY_SIZE); - CG(active_op_array) = op_array; - - if (zend_ast_process) { - zend_ast_process(CG(ast)); - } - - zend_file_context_begin(&original_file_context); - zend_oparray_context_begin(&original_oparray_context); - zend_compile_top_stmt(CG(ast)); - zend_emit_final_return(NULL); - op_array->line_start = 1; - op_array->line_end = CG(zend_lineno); - pass_two(op_array); - zend_oparray_context_end(&original_oparray_context); - zend_file_context_end(&original_file_context); - - CG(active_op_array) = original_active_op_array; - } - - zend_ast_destroy(CG(ast)); - zend_arena_destroy(CG(ast_arena)); + op_array = zend_compile(ZEND_EVAL_CODE); } zend_restore_lexical_state(&original_lex_state); zval_dtor(&tmp); - CG(in_compilation) = original_in_compilation; + return op_array; } @@ -1117,7 +1093,7 @@ restart: SCNG(yy_text) = YYCURSOR; -#line 1121 "Zend/zend_language_scanner.c" +#line 1097 "Zend/zend_language_scanner.c" { YYCTYPE yych; unsigned int yyaccept = 0; @@ -1171,7 +1147,7 @@ yyc_INITIAL: yy3: YYDEBUG(3, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1813 "Zend/zend_language_scanner.l" +#line 1789 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -1216,7 +1192,7 @@ inline_char_handler: HANDLE_NEWLINES(yytext, yyleng); RETURN_TOKEN(T_INLINE_HTML); } -#line 1220 "Zend/zend_language_scanner.c" +#line 1196 "Zend/zend_language_scanner.c" yy4: YYDEBUG(4, *YYCURSOR); yych = *++YYCURSOR; @@ -1234,7 +1210,7 @@ yy5: yy6: YYDEBUG(6, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1804 "Zend/zend_language_scanner.l" +#line 1780 "Zend/zend_language_scanner.l" { if (CG(short_tags)) { BEGIN(ST_IN_SCRIPTING); @@ -1243,18 +1219,18 @@ yy6: goto inline_char_handler; } } -#line 1247 "Zend/zend_language_scanner.c" +#line 1223 "Zend/zend_language_scanner.c" yy7: YYDEBUG(7, *YYCURSOR); ++YYCURSOR; YYDEBUG(8, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1791 "Zend/zend_language_scanner.l" +#line 1767 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN(T_OPEN_TAG_WITH_ECHO); } -#line 1258 "Zend/zend_language_scanner.c" +#line 1234 "Zend/zend_language_scanner.c" yy9: YYDEBUG(9, *YYCURSOR); yych = *++YYCURSOR; @@ -1285,13 +1261,13 @@ yy13: yy14: YYDEBUG(14, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1797 "Zend/zend_language_scanner.l" +#line 1773 "Zend/zend_language_scanner.l" { HANDLE_NEWLINE(yytext[yyleng-1]); BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN(T_OPEN_TAG); } -#line 1295 "Zend/zend_language_scanner.c" +#line 1271 "Zend/zend_language_scanner.c" yy15: YYDEBUG(15, *YYCURSOR); ++YYCURSOR; @@ -1361,7 +1337,7 @@ yyc_ST_BACKQUOTE: yy19: YYDEBUG(19, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2223 "Zend/zend_language_scanner.l" +#line 2199 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -1402,7 +1378,7 @@ yy19: zend_scan_escape_string(zendlval, yytext, yyleng, '`'); RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE); } -#line 1406 "Zend/zend_language_scanner.c" +#line 1382 "Zend/zend_language_scanner.c" yy20: YYDEBUG(20, *YYCURSOR); yych = *++YYCURSOR; @@ -1413,12 +1389,12 @@ yy21: ++YYCURSOR; YYDEBUG(22, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2167 "Zend/zend_language_scanner.l" +#line 2143 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN('`'); } -#line 1422 "Zend/zend_language_scanner.c" +#line 1398 "Zend/zend_language_scanner.c" yy23: YYDEBUG(23, *YYCURSOR); yych = *++YYCURSOR; @@ -1428,14 +1404,14 @@ yy24: ++YYCURSOR; YYDEBUG(25, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2154 "Zend/zend_language_scanner.l" +#line 2130 "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 1439 "Zend/zend_language_scanner.c" +#line 1415 "Zend/zend_language_scanner.c" yy26: YYDEBUG(26, *YYCURSOR); yyaccept = 0; @@ -1451,23 +1427,23 @@ yy26: yy28: YYDEBUG(28, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1878 "Zend/zend_language_scanner.l" +#line 1854 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 1460 "Zend/zend_language_scanner.c" +#line 1436 "Zend/zend_language_scanner.c" yy29: YYDEBUG(29, *YYCURSOR); ++YYCURSOR; YYDEBUG(30, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1596 "Zend/zend_language_scanner.l" +#line 1572 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME); RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES); } -#line 1471 "Zend/zend_language_scanner.c" +#line 1447 "Zend/zend_language_scanner.c" yy31: YYDEBUG(31, *YYCURSOR); yych = *++YYCURSOR; @@ -1481,14 +1457,14 @@ yy33: ++YYCURSOR; YYDEBUG(34, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1871 "Zend/zend_language_scanner.l" +#line 1847 "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 1492 "Zend/zend_language_scanner.c" +#line 1468 "Zend/zend_language_scanner.c" yy35: YYDEBUG(35, *YYCURSOR); yych = *++YYCURSOR; @@ -1506,14 +1482,14 @@ yy36: ++YYCURSOR; YYDEBUG(37, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1862 "Zend/zend_language_scanner.l" +#line 1838 "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 1517 "Zend/zend_language_scanner.c" +#line 1493 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_DOUBLE_QUOTES: @@ -1581,7 +1557,7 @@ yy40: yy41: YYDEBUG(41, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2173 "Zend/zend_language_scanner.l" +#line 2149 "Zend/zend_language_scanner.l" { if (GET_DOUBLE_QUOTES_SCANNED_LENGTH()) { YYCURSOR += GET_DOUBLE_QUOTES_SCANNED_LENGTH() - 1; @@ -1630,7 +1606,7 @@ double_quotes_scan_done: zend_scan_escape_string(zendlval, yytext, yyleng, '"'); RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE); } -#line 1634 "Zend/zend_language_scanner.c" +#line 1610 "Zend/zend_language_scanner.c" yy42: YYDEBUG(42, *YYCURSOR); yych = *++YYCURSOR; @@ -1641,12 +1617,12 @@ yy43: ++YYCURSOR; YYDEBUG(44, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2162 "Zend/zend_language_scanner.l" +#line 2138 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN('"'); } -#line 1650 "Zend/zend_language_scanner.c" +#line 1626 "Zend/zend_language_scanner.c" yy45: YYDEBUG(45, *YYCURSOR); yych = *++YYCURSOR; @@ -1656,14 +1632,14 @@ yy46: ++YYCURSOR; YYDEBUG(47, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2154 "Zend/zend_language_scanner.l" +#line 2130 "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 1667 "Zend/zend_language_scanner.c" +#line 1643 "Zend/zend_language_scanner.c" yy48: YYDEBUG(48, *YYCURSOR); yyaccept = 0; @@ -1679,23 +1655,23 @@ yy48: yy50: YYDEBUG(50, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1878 "Zend/zend_language_scanner.l" +#line 1854 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 1688 "Zend/zend_language_scanner.c" +#line 1664 "Zend/zend_language_scanner.c" yy51: YYDEBUG(51, *YYCURSOR); ++YYCURSOR; YYDEBUG(52, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1596 "Zend/zend_language_scanner.l" +#line 1572 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME); RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES); } -#line 1699 "Zend/zend_language_scanner.c" +#line 1675 "Zend/zend_language_scanner.c" yy53: YYDEBUG(53, *YYCURSOR); yych = *++YYCURSOR; @@ -1709,14 +1685,14 @@ yy55: ++YYCURSOR; YYDEBUG(56, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1871 "Zend/zend_language_scanner.l" +#line 1847 "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 1720 "Zend/zend_language_scanner.c" +#line 1696 "Zend/zend_language_scanner.c" yy57: YYDEBUG(57, *YYCURSOR); yych = *++YYCURSOR; @@ -1734,14 +1710,14 @@ yy58: ++YYCURSOR; YYDEBUG(59, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1862 "Zend/zend_language_scanner.l" +#line 1838 "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 1745 "Zend/zend_language_scanner.c" +#line 1721 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_END_HEREDOC: @@ -1752,7 +1728,7 @@ yyc_ST_END_HEREDOC: ++YYCURSOR; YYDEBUG(63, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2140 "Zend/zend_language_scanner.l" +#line 2116 "Zend/zend_language_scanner.l" { zend_heredoc_label *heredoc_label = zend_ptr_stack_pop(&SCNG(heredoc_label_stack)); @@ -1765,7 +1741,7 @@ yyc_ST_END_HEREDOC: BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN(T_END_HEREDOC); } -#line 1769 "Zend/zend_language_scanner.c" +#line 1745 "Zend/zend_language_scanner.c" /* *********************************** */ yyc_ST_HEREDOC: { @@ -1827,7 +1803,7 @@ yy66: yy67: YYDEBUG(67, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2265 "Zend/zend_language_scanner.l" +#line 2241 "Zend/zend_language_scanner.l" { int newline = 0; @@ -1900,7 +1876,7 @@ heredoc_scan_done: zend_scan_escape_string(zendlval, yytext, yyleng - newline, 0); RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE); } -#line 1904 "Zend/zend_language_scanner.c" +#line 1880 "Zend/zend_language_scanner.c" yy68: YYDEBUG(68, *YYCURSOR); yych = *++YYCURSOR; @@ -1915,14 +1891,14 @@ yy70: ++YYCURSOR; YYDEBUG(71, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2154 "Zend/zend_language_scanner.l" +#line 2130 "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 1926 "Zend/zend_language_scanner.c" +#line 1902 "Zend/zend_language_scanner.c" yy72: YYDEBUG(72, *YYCURSOR); yyaccept = 0; @@ -1938,23 +1914,23 @@ yy72: yy74: YYDEBUG(74, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1878 "Zend/zend_language_scanner.l" +#line 1854 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 1947 "Zend/zend_language_scanner.c" +#line 1923 "Zend/zend_language_scanner.c" yy75: YYDEBUG(75, *YYCURSOR); ++YYCURSOR; YYDEBUG(76, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1596 "Zend/zend_language_scanner.l" +#line 1572 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME); RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES); } -#line 1958 "Zend/zend_language_scanner.c" +#line 1934 "Zend/zend_language_scanner.c" yy77: YYDEBUG(77, *YYCURSOR); yych = *++YYCURSOR; @@ -1968,14 +1944,14 @@ yy79: ++YYCURSOR; YYDEBUG(80, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1871 "Zend/zend_language_scanner.l" +#line 1847 "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 1979 "Zend/zend_language_scanner.c" +#line 1955 "Zend/zend_language_scanner.c" yy81: YYDEBUG(81, *YYCURSOR); yych = *++YYCURSOR; @@ -1993,14 +1969,14 @@ yy82: ++YYCURSOR; YYDEBUG(83, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1862 "Zend/zend_language_scanner.l" +#line 1838 "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 2004 "Zend/zend_language_scanner.c" +#line 1980 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_IN_SCRIPTING: @@ -2183,12 +2159,12 @@ yy86: yy87: YYDEBUG(87, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1901 "Zend/zend_language_scanner.l" +#line 1877 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, yytext, yyleng); RETURN_TOKEN(T_STRING); } -#line 2192 "Zend/zend_language_scanner.c" +#line 2168 "Zend/zend_language_scanner.c" yy88: YYDEBUG(88, *YYCURSOR); yych = *++YYCURSOR; @@ -2420,11 +2396,11 @@ yy101: yy102: YYDEBUG(102, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1585 "Zend/zend_language_scanner.l" +#line 1561 "Zend/zend_language_scanner.l" { RETURN_TOKEN(yytext[0]); } -#line 2428 "Zend/zend_language_scanner.c" +#line 2404 "Zend/zend_language_scanner.c" yy103: YYDEBUG(103, *YYCURSOR); ++YYCURSOR; @@ -2433,12 +2409,12 @@ yy103: yy104: YYDEBUG(104, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1300 "Zend/zend_language_scanner.l" +#line 1276 "Zend/zend_language_scanner.l" { HANDLE_NEWLINES(yytext, yyleng); RETURN_TOKEN(T_WHITESPACE); } -#line 2442 "Zend/zend_language_scanner.c" +#line 2418 "Zend/zend_language_scanner.c" yy105: YYDEBUG(105, *YYCURSOR); yych = *++YYCURSOR; @@ -2449,11 +2425,11 @@ yy106: ++YYCURSOR; YYDEBUG(107, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1325 "Zend/zend_language_scanner.l" +#line 1301 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NS_SEPARATOR); } -#line 2457 "Zend/zend_language_scanner.c" +#line 2433 "Zend/zend_language_scanner.c" yy108: YYDEBUG(108, *YYCURSOR); yyaccept = 1; @@ -2682,18 +2658,18 @@ yy131: ++YYCURSOR; YYDEBUG(132, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1590 "Zend/zend_language_scanner.l" +#line 1566 "Zend/zend_language_scanner.l" { yy_push_state(ST_IN_SCRIPTING); RETURN_TOKEN('{'); } -#line 2691 "Zend/zend_language_scanner.c" +#line 2667 "Zend/zend_language_scanner.c" yy133: YYDEBUG(133, *YYCURSOR); ++YYCURSOR; YYDEBUG(134, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1602 "Zend/zend_language_scanner.l" +#line 1578 "Zend/zend_language_scanner.l" { RESET_DOC_COMMENT(); if (!zend_stack_is_empty(&SCNG(state_stack))) { @@ -2701,7 +2677,7 @@ yy133: } RETURN_TOKEN('}'); } -#line 2705 "Zend/zend_language_scanner.c" +#line 2681 "Zend/zend_language_scanner.c" yy135: YYDEBUG(135, *YYCURSOR); yyaccept = 2; @@ -2729,7 +2705,7 @@ yy135: yy136: YYDEBUG(136, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1655 "Zend/zend_language_scanner.l" +#line 1631 "Zend/zend_language_scanner.l" { char *end; if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */ @@ -2774,7 +2750,7 @@ yy136: ZEND_ASSERT(!errno); RETURN_TOKEN(T_LNUMBER); } -#line 2778 "Zend/zend_language_scanner.c" +#line 2754 "Zend/zend_language_scanner.c" yy137: YYDEBUG(137, *YYCURSOR); yyaccept = 2; @@ -2802,7 +2778,7 @@ yy139: yy140: YYDEBUG(140, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1907 "Zend/zend_language_scanner.l" +#line 1883 "Zend/zend_language_scanner.l" { while (YYCURSOR < YYLIMIT) { switch (*YYCURSOR++) { @@ -2831,14 +2807,14 @@ yy140: RETURN_TOKEN(T_COMMENT); } -#line 2835 "Zend/zend_language_scanner.c" +#line 2811 "Zend/zend_language_scanner.c" yy141: YYDEBUG(141, *YYCURSOR); ++YYCURSOR; yy142: YYDEBUG(142, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1975 "Zend/zend_language_scanner.l" +#line 1951 "Zend/zend_language_scanner.l" { register char *s, *t; char *end; @@ -2906,14 +2882,14 @@ yy142: } RETURN_TOKEN(T_CONSTANT_ENCAPSED_STRING); } -#line 2910 "Zend/zend_language_scanner.c" +#line 2886 "Zend/zend_language_scanner.c" yy143: YYDEBUG(143, *YYCURSOR); ++YYCURSOR; yy144: YYDEBUG(144, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2044 "Zend/zend_language_scanner.l" +#line 2020 "Zend/zend_language_scanner.l" { int bprefix = (yytext[0] != '"') ? 1 : 0; @@ -2954,24 +2930,24 @@ yy144: BEGIN(ST_DOUBLE_QUOTES); RETURN_TOKEN('"'); } -#line 2958 "Zend/zend_language_scanner.c" +#line 2934 "Zend/zend_language_scanner.c" yy145: YYDEBUG(145, *YYCURSOR); ++YYCURSOR; YYDEBUG(146, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2134 "Zend/zend_language_scanner.l" +#line 2110 "Zend/zend_language_scanner.l" { BEGIN(ST_BACKQUOTE); RETURN_TOKEN('`'); } -#line 2969 "Zend/zend_language_scanner.c" +#line 2945 "Zend/zend_language_scanner.c" yy147: YYDEBUG(147, *YYCURSOR); ++YYCURSOR; YYDEBUG(148, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2396 "Zend/zend_language_scanner.l" +#line 2372 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -2980,7 +2956,7 @@ yy147: zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE); goto restart; } -#line 2984 "Zend/zend_language_scanner.c" +#line 2960 "Zend/zend_language_scanner.c" yy149: YYDEBUG(149, *YYCURSOR); ++YYCURSOR; @@ -3007,7 +2983,7 @@ yy151: yy153: YYDEBUG(153, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1749 "Zend/zend_language_scanner.l" +#line 1725 "Zend/zend_language_scanner.l" { const char *end; @@ -3016,7 +2992,7 @@ yy153: ZEND_ASSERT(end == yytext + yyleng); RETURN_TOKEN(T_DNUMBER); } -#line 3020 "Zend/zend_language_scanner.c" +#line 2996 "Zend/zend_language_scanner.c" yy154: YYDEBUG(154, *YYCURSOR); yyaccept = 2; @@ -3112,7 +3088,7 @@ yy163: } YYDEBUG(165, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1627 "Zend/zend_language_scanner.l" +#line 1603 "Zend/zend_language_scanner.l" { char *bin = yytext + 2; /* Skip "0b" */ int len = yyleng - 2; @@ -3140,7 +3116,7 @@ yy163: RETURN_TOKEN(T_DNUMBER); } } -#line 3144 "Zend/zend_language_scanner.c" +#line 3120 "Zend/zend_language_scanner.c" yy166: YYDEBUG(166, *YYCURSOR); ++YYCURSOR; @@ -3152,7 +3128,7 @@ yy166: } YYDEBUG(168, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1700 "Zend/zend_language_scanner.l" +#line 1676 "Zend/zend_language_scanner.l" { char *hex = yytext + 2; /* Skip "0x" */ int len = yyleng - 2; @@ -3180,7 +3156,7 @@ yy166: RETURN_TOKEN(T_DNUMBER); } } -#line 3184 "Zend/zend_language_scanner.c" +#line 3160 "Zend/zend_language_scanner.c" yy169: YYDEBUG(169, *YYCURSOR); ++YYCURSOR; @@ -3205,12 +3181,12 @@ yy169: yy171: YYDEBUG(171, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1878 "Zend/zend_language_scanner.l" +#line 1854 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 3214 "Zend/zend_language_scanner.c" +#line 3190 "Zend/zend_language_scanner.c" yy172: YYDEBUG(172, *YYCURSOR); yych = *++YYCURSOR; @@ -3224,11 +3200,11 @@ yy173: } YYDEBUG(174, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1573 "Zend/zend_language_scanner.l" +#line 1549 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LOGICAL_XOR); } -#line 3232 "Zend/zend_language_scanner.c" +#line 3208 "Zend/zend_language_scanner.c" yy175: YYDEBUG(175, *YYCURSOR); ++YYCURSOR; @@ -3237,71 +3213,71 @@ yy175: } YYDEBUG(176, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1565 "Zend/zend_language_scanner.l" +#line 1541 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LOGICAL_OR); } -#line 3245 "Zend/zend_language_scanner.c" +#line 3221 "Zend/zend_language_scanner.c" yy177: YYDEBUG(177, *YYCURSOR); ++YYCURSOR; YYDEBUG(178, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1553 "Zend/zend_language_scanner.l" +#line 1529 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_XOR_EQUAL); } -#line 3255 "Zend/zend_language_scanner.c" +#line 3231 "Zend/zend_language_scanner.c" yy179: YYDEBUG(179, *YYCURSOR); ++YYCURSOR; YYDEBUG(180, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1557 "Zend/zend_language_scanner.l" +#line 1533 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BOOLEAN_OR); } -#line 3265 "Zend/zend_language_scanner.c" +#line 3241 "Zend/zend_language_scanner.c" yy181: YYDEBUG(181, *YYCURSOR); ++YYCURSOR; YYDEBUG(182, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1549 "Zend/zend_language_scanner.l" +#line 1525 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_OR_EQUAL); } -#line 3275 "Zend/zend_language_scanner.c" +#line 3251 "Zend/zend_language_scanner.c" yy183: YYDEBUG(183, *YYCURSOR); ++YYCURSOR; YYDEBUG(184, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1561 "Zend/zend_language_scanner.l" +#line 1537 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BOOLEAN_AND); } -#line 3285 "Zend/zend_language_scanner.c" +#line 3261 "Zend/zend_language_scanner.c" yy185: YYDEBUG(185, *YYCURSOR); ++YYCURSOR; YYDEBUG(186, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1545 "Zend/zend_language_scanner.l" +#line 1521 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_AND_EQUAL); } -#line 3295 "Zend/zend_language_scanner.c" +#line 3271 "Zend/zend_language_scanner.c" yy187: YYDEBUG(187, *YYCURSOR); ++YYCURSOR; YYDEBUG(188, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1533 "Zend/zend_language_scanner.l" +#line 1509 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_MOD_EQUAL); } -#line 3305 "Zend/zend_language_scanner.c" +#line 3281 "Zend/zend_language_scanner.c" yy189: YYDEBUG(189, *YYCURSOR); yyaccept = 4; @@ -3310,7 +3286,7 @@ yy189: yy190: YYDEBUG(190, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1936 "Zend/zend_language_scanner.l" +#line 1912 "Zend/zend_language_scanner.l" { int doc_com; @@ -3343,7 +3319,7 @@ yy190: RETURN_TOKEN(T_COMMENT); } -#line 3347 "Zend/zend_language_scanner.c" +#line 3323 "Zend/zend_language_scanner.c" yy191: YYDEBUG(191, *YYCURSOR); yych = *++YYCURSOR; @@ -3353,11 +3329,11 @@ yy192: ++YYCURSOR; YYDEBUG(193, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1525 "Zend/zend_language_scanner.l" +#line 1501 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DIV_EQUAL); } -#line 3361 "Zend/zend_language_scanner.c" +#line 3337 "Zend/zend_language_scanner.c" yy194: YYDEBUG(194, *YYCURSOR); yych = *++YYCURSOR; @@ -3381,62 +3357,62 @@ yy197: if ((yych = *YYCURSOR) == '=') goto yy201; YYDEBUG(198, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1517 "Zend/zend_language_scanner.l" +#line 1493 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_POW); } -#line 3389 "Zend/zend_language_scanner.c" +#line 3365 "Zend/zend_language_scanner.c" yy199: YYDEBUG(199, *YYCURSOR); ++YYCURSOR; YYDEBUG(200, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1513 "Zend/zend_language_scanner.l" +#line 1489 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_MUL_EQUAL); } -#line 3399 "Zend/zend_language_scanner.c" +#line 3375 "Zend/zend_language_scanner.c" yy201: YYDEBUG(201, *YYCURSOR); ++YYCURSOR; YYDEBUG(202, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1521 "Zend/zend_language_scanner.l" +#line 1497 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_POW_EQUAL); } -#line 3409 "Zend/zend_language_scanner.c" +#line 3385 "Zend/zend_language_scanner.c" yy203: YYDEBUG(203, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) == '=') goto yy207; YYDEBUG(204, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1581 "Zend/zend_language_scanner.l" +#line 1557 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SR); } -#line 3420 "Zend/zend_language_scanner.c" +#line 3396 "Zend/zend_language_scanner.c" yy205: YYDEBUG(205, *YYCURSOR); ++YYCURSOR; YYDEBUG(206, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1501 "Zend/zend_language_scanner.l" +#line 1477 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_GREATER_OR_EQUAL); } -#line 3430 "Zend/zend_language_scanner.c" +#line 3406 "Zend/zend_language_scanner.c" yy207: YYDEBUG(207, *YYCURSOR); ++YYCURSOR; YYDEBUG(208, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1541 "Zend/zend_language_scanner.l" +#line 1517 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SR_EQUAL); } -#line 3440 "Zend/zend_language_scanner.c" +#line 3416 "Zend/zend_language_scanner.c" yy209: YYDEBUG(209, *YYCURSOR); yyaccept = 5; @@ -3447,53 +3423,53 @@ yy209: yy210: YYDEBUG(210, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1577 "Zend/zend_language_scanner.l" +#line 1553 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SL); } -#line 3455 "Zend/zend_language_scanner.c" +#line 3431 "Zend/zend_language_scanner.c" yy211: YYDEBUG(211, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) == '>') goto yy215; YYDEBUG(212, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1497 "Zend/zend_language_scanner.l" +#line 1473 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_SMALLER_OR_EQUAL); } -#line 3466 "Zend/zend_language_scanner.c" +#line 3442 "Zend/zend_language_scanner.c" yy213: YYDEBUG(213, *YYCURSOR); ++YYCURSOR; yy214: YYDEBUG(214, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1489 "Zend/zend_language_scanner.l" +#line 1465 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_NOT_EQUAL); } -#line 3477 "Zend/zend_language_scanner.c" +#line 3453 "Zend/zend_language_scanner.c" yy215: YYDEBUG(215, *YYCURSOR); ++YYCURSOR; YYDEBUG(216, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1493 "Zend/zend_language_scanner.l" +#line 1469 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SPACESHIP); } -#line 3487 "Zend/zend_language_scanner.c" +#line 3463 "Zend/zend_language_scanner.c" yy217: YYDEBUG(217, *YYCURSOR); ++YYCURSOR; YYDEBUG(218, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1537 "Zend/zend_language_scanner.l" +#line 1513 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SL_EQUAL); } -#line 3497 "Zend/zend_language_scanner.c" +#line 3473 "Zend/zend_language_scanner.c" yy219: YYDEBUG(219, *YYCURSOR); ++YYCURSOR; @@ -3598,7 +3574,7 @@ yy228: yy229: YYDEBUG(229, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2086 "Zend/zend_language_scanner.l" +#line 2062 "Zend/zend_language_scanner.l" { char *s; int bprefix = (yytext[0] != '<') ? 1 : 0; @@ -3645,7 +3621,7 @@ yy229: RETURN_TOKEN(T_START_HEREDOC); } -#line 3649 "Zend/zend_language_scanner.c" +#line 3625 "Zend/zend_language_scanner.c" yy230: YYDEBUG(230, *YYCURSOR); yych = *++YYCURSOR; @@ -3685,31 +3661,31 @@ yy233: ++YYCURSOR; YYDEBUG(235, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1481 "Zend/zend_language_scanner.l" +#line 1457 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_NOT_IDENTICAL); } -#line 3693 "Zend/zend_language_scanner.c" +#line 3669 "Zend/zend_language_scanner.c" yy236: YYDEBUG(236, *YYCURSOR); ++YYCURSOR; YYDEBUG(237, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1505 "Zend/zend_language_scanner.l" +#line 1481 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PLUS_EQUAL); } -#line 3703 "Zend/zend_language_scanner.c" +#line 3679 "Zend/zend_language_scanner.c" yy238: YYDEBUG(238, *YYCURSOR); ++YYCURSOR; YYDEBUG(239, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1469 "Zend/zend_language_scanner.l" +#line 1445 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INC); } -#line 3713 "Zend/zend_language_scanner.c" +#line 3689 "Zend/zend_language_scanner.c" yy240: YYDEBUG(240, *YYCURSOR); yych = *++YYCURSOR; @@ -3728,42 +3704,42 @@ yy242: } YYDEBUG(243, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1457 "Zend/zend_language_scanner.l" +#line 1433 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LIST); } -#line 3736 "Zend/zend_language_scanner.c" +#line 3712 "Zend/zend_language_scanner.c" yy244: YYDEBUG(244, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) == '=') goto yy248; YYDEBUG(245, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1485 "Zend/zend_language_scanner.l" +#line 1461 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_EQUAL); } -#line 3747 "Zend/zend_language_scanner.c" +#line 3723 "Zend/zend_language_scanner.c" yy246: YYDEBUG(246, *YYCURSOR); ++YYCURSOR; YYDEBUG(247, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1453 "Zend/zend_language_scanner.l" +#line 1429 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DOUBLE_ARROW); } -#line 3757 "Zend/zend_language_scanner.c" +#line 3733 "Zend/zend_language_scanner.c" yy248: YYDEBUG(248, *YYCURSOR); ++YYCURSOR; YYDEBUG(249, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1477 "Zend/zend_language_scanner.l" +#line 1453 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_IDENTICAL); } -#line 3767 "Zend/zend_language_scanner.c" +#line 3743 "Zend/zend_language_scanner.c" yy250: YYDEBUG(250, *YYCURSOR); yych = *++YYCURSOR; @@ -3893,11 +3869,11 @@ yy266: } YYDEBUG(269, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1786 "Zend/zend_language_scanner.l" +#line 1762 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NS_C); } -#line 3901 "Zend/zend_language_scanner.c" +#line 3877 "Zend/zend_language_scanner.c" yy270: YYDEBUG(270, *YYCURSOR); yych = *++YYCURSOR; @@ -3917,11 +3893,11 @@ yy271: } YYDEBUG(274, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1782 "Zend/zend_language_scanner.l" +#line 1758 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DIR); } -#line 3925 "Zend/zend_language_scanner.c" +#line 3901 "Zend/zend_language_scanner.c" yy275: YYDEBUG(275, *YYCURSOR); yych = *++YYCURSOR; @@ -3946,11 +3922,11 @@ yy277: } YYDEBUG(280, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1774 "Zend/zend_language_scanner.l" +#line 1750 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LINE); } -#line 3954 "Zend/zend_language_scanner.c" +#line 3930 "Zend/zend_language_scanner.c" yy281: YYDEBUG(281, *YYCURSOR); yych = *++YYCURSOR; @@ -3985,11 +3961,11 @@ yy285: } YYDEBUG(288, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1770 "Zend/zend_language_scanner.l" +#line 1746 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_METHOD_C); } -#line 3993 "Zend/zend_language_scanner.c" +#line 3969 "Zend/zend_language_scanner.c" yy289: YYDEBUG(289, *YYCURSOR); yych = *++YYCURSOR; @@ -4040,11 +4016,11 @@ yy296: } YYDEBUG(299, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1766 "Zend/zend_language_scanner.l" +#line 1742 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FUNC_C); } -#line 4048 "Zend/zend_language_scanner.c" +#line 4024 "Zend/zend_language_scanner.c" yy300: YYDEBUG(300, *YYCURSOR); yych = *++YYCURSOR; @@ -4064,11 +4040,11 @@ yy301: } YYDEBUG(304, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1778 "Zend/zend_language_scanner.l" +#line 1754 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FILE); } -#line 4072 "Zend/zend_language_scanner.c" +#line 4048 "Zend/zend_language_scanner.c" yy305: YYDEBUG(305, *YYCURSOR); yych = *++YYCURSOR; @@ -4098,11 +4074,11 @@ yy308: } YYDEBUG(311, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1762 "Zend/zend_language_scanner.l" +#line 1738 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_TRAIT_C); } -#line 4106 "Zend/zend_language_scanner.c" +#line 4082 "Zend/zend_language_scanner.c" yy312: YYDEBUG(312, *YYCURSOR); yych = *++YYCURSOR; @@ -4132,11 +4108,11 @@ yy315: } YYDEBUG(318, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1758 "Zend/zend_language_scanner.l" +#line 1734 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CLASS_C); } -#line 4140 "Zend/zend_language_scanner.c" +#line 4116 "Zend/zend_language_scanner.c" yy319: YYDEBUG(319, *YYCURSOR); yych = *++YYCURSOR; @@ -4198,11 +4174,11 @@ yy330: } YYDEBUG(331, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1421 "Zend/zend_language_scanner.l" +#line 1397 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_HALT_COMPILER); } -#line 4206 "Zend/zend_language_scanner.c" +#line 4182 "Zend/zend_language_scanner.c" yy332: YYDEBUG(332, *YYCURSOR); yych = *++YYCURSOR; @@ -4222,11 +4198,11 @@ yy334: } YYDEBUG(335, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1401 "Zend/zend_language_scanner.l" +#line 1377 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_USE); } -#line 4230 "Zend/zend_language_scanner.c" +#line 4206 "Zend/zend_language_scanner.c" yy336: YYDEBUG(336, *YYCURSOR); yych = *++YYCURSOR; @@ -4245,11 +4221,11 @@ yy338: } YYDEBUG(339, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1449 "Zend/zend_language_scanner.l" +#line 1425 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_UNSET); } -#line 4253 "Zend/zend_language_scanner.c" +#line 4229 "Zend/zend_language_scanner.c" yy340: YYDEBUG(340, *YYCURSOR); ++YYCURSOR; @@ -4421,11 +4397,11 @@ yy355: ++YYCURSOR; YYDEBUG(357, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1349 "Zend/zend_language_scanner.l" +#line 1325 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INT_CAST); } -#line 4429 "Zend/zend_language_scanner.c" +#line 4405 "Zend/zend_language_scanner.c" yy358: YYDEBUG(358, *YYCURSOR); yych = *++YYCURSOR; @@ -4469,11 +4445,11 @@ yy363: ++YYCURSOR; YYDEBUG(366, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1353 "Zend/zend_language_scanner.l" +#line 1329 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DOUBLE_CAST); } -#line 4477 "Zend/zend_language_scanner.c" +#line 4453 "Zend/zend_language_scanner.c" yy367: YYDEBUG(367, *YYCURSOR); yych = *++YYCURSOR; @@ -4543,11 +4519,11 @@ yy377: ++YYCURSOR; YYDEBUG(380, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1357 "Zend/zend_language_scanner.l" +#line 1333 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_STRING_CAST); } -#line 4551 "Zend/zend_language_scanner.c" +#line 4527 "Zend/zend_language_scanner.c" yy381: YYDEBUG(381, *YYCURSOR); yych = *++YYCURSOR; @@ -4580,11 +4556,11 @@ yy384: ++YYCURSOR; YYDEBUG(387, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1361 "Zend/zend_language_scanner.l" +#line 1337 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ARRAY_CAST); } -#line 4588 "Zend/zend_language_scanner.c" +#line 4564 "Zend/zend_language_scanner.c" yy388: YYDEBUG(388, *YYCURSOR); yych = *++YYCURSOR; @@ -4622,11 +4598,11 @@ yy392: ++YYCURSOR; YYDEBUG(395, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1365 "Zend/zend_language_scanner.l" +#line 1341 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_OBJECT_CAST); } -#line 4630 "Zend/zend_language_scanner.c" +#line 4606 "Zend/zend_language_scanner.c" yy396: YYDEBUG(396, *YYCURSOR); yych = *++YYCURSOR; @@ -4667,11 +4643,11 @@ yy401: ++YYCURSOR; YYDEBUG(403, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1369 "Zend/zend_language_scanner.l" +#line 1345 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BOOL_CAST); } -#line 4675 "Zend/zend_language_scanner.c" +#line 4651 "Zend/zend_language_scanner.c" yy404: YYDEBUG(404, *YYCURSOR); yych = *++YYCURSOR; @@ -4731,11 +4707,11 @@ yy412: ++YYCURSOR; YYDEBUG(415, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1373 "Zend/zend_language_scanner.l" +#line 1349 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_UNSET_CAST); } -#line 4739 "Zend/zend_language_scanner.c" +#line 4715 "Zend/zend_language_scanner.c" yy416: YYDEBUG(416, *YYCURSOR); yych = *++YYCURSOR; @@ -4749,11 +4725,11 @@ yy417: } YYDEBUG(418, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1345 "Zend/zend_language_scanner.l" +#line 1321 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_VAR); } -#line 4757 "Zend/zend_language_scanner.c" +#line 4733 "Zend/zend_language_scanner.c" yy419: YYDEBUG(419, *YYCURSOR); yych = *++YYCURSOR; @@ -4773,11 +4749,11 @@ yy421: } YYDEBUG(422, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1337 "Zend/zend_language_scanner.l" +#line 1313 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NEW); } -#line 4781 "Zend/zend_language_scanner.c" +#line 4757 "Zend/zend_language_scanner.c" yy423: YYDEBUG(423, *YYCURSOR); yych = *++YYCURSOR; @@ -4816,11 +4792,11 @@ yy429: } YYDEBUG(430, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1397 "Zend/zend_language_scanner.l" +#line 1373 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NAMESPACE); } -#line 4824 "Zend/zend_language_scanner.c" +#line 4800 "Zend/zend_language_scanner.c" yy431: YYDEBUG(431, *YYCURSOR); ++YYCURSOR; @@ -4829,22 +4805,22 @@ yy431: yy432: YYDEBUG(432, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1969 "Zend/zend_language_scanner.l" +#line 1945 "Zend/zend_language_scanner.l" { BEGIN(INITIAL); RETURN_TOKEN(T_CLOSE_TAG); /* implicit ';' at php-end tag */ } -#line 4838 "Zend/zend_language_scanner.c" +#line 4814 "Zend/zend_language_scanner.c" yy433: YYDEBUG(433, *YYCURSOR); ++YYCURSOR; YYDEBUG(434, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1333 "Zend/zend_language_scanner.l" +#line 1309 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_COALESCE); } -#line 4848 "Zend/zend_language_scanner.c" +#line 4824 "Zend/zend_language_scanner.c" yy435: YYDEBUG(435, *YYCURSOR); yych = *++YYCURSOR; @@ -4875,11 +4851,11 @@ yy439: ++YYCURSOR; YYDEBUG(440, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1529 "Zend/zend_language_scanner.l" +#line 1505 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CONCAT_EQUAL); } -#line 4883 "Zend/zend_language_scanner.c" +#line 4859 "Zend/zend_language_scanner.c" yy441: YYDEBUG(441, *YYCURSOR); yych = *++YYCURSOR; @@ -4888,21 +4864,21 @@ yy441: ++YYCURSOR; YYDEBUG(443, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1329 "Zend/zend_language_scanner.l" +#line 1305 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ELLIPSIS); } -#line 4896 "Zend/zend_language_scanner.c" +#line 4872 "Zend/zend_language_scanner.c" yy444: YYDEBUG(444, *YYCURSOR); ++YYCURSOR; YYDEBUG(445, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1321 "Zend/zend_language_scanner.l" +#line 1297 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PAAMAYIM_NEKUDOTAYIM); } -#line 4906 "Zend/zend_language_scanner.c" +#line 4882 "Zend/zend_language_scanner.c" yy446: YYDEBUG(446, *YYCURSOR); ++YYCURSOR; @@ -4924,32 +4900,32 @@ yy448: ++YYCURSOR; YYDEBUG(449, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1509 "Zend/zend_language_scanner.l" +#line 1485 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_MINUS_EQUAL); } -#line 4932 "Zend/zend_language_scanner.c" +#line 4908 "Zend/zend_language_scanner.c" yy450: YYDEBUG(450, *YYCURSOR); ++YYCURSOR; YYDEBUG(451, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1473 "Zend/zend_language_scanner.l" +#line 1449 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DEC); } -#line 4942 "Zend/zend_language_scanner.c" +#line 4918 "Zend/zend_language_scanner.c" yy452: YYDEBUG(452, *YYCURSOR); ++YYCURSOR; YYDEBUG(453, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1295 "Zend/zend_language_scanner.l" +#line 1271 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_PROPERTY); RETURN_TOKEN(T_OBJECT_OPERATOR); } -#line 4953 "Zend/zend_language_scanner.c" +#line 4929 "Zend/zend_language_scanner.c" yy454: YYDEBUG(454, *YYCURSOR); yych = *++YYCURSOR; @@ -4994,11 +4970,11 @@ yy459: } YYDEBUG(460, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1445 "Zend/zend_language_scanner.l" +#line 1421 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PUBLIC); } -#line 5002 "Zend/zend_language_scanner.c" +#line 4978 "Zend/zend_language_scanner.c" yy461: YYDEBUG(461, *YYCURSOR); yych = *++YYCURSOR; @@ -5053,11 +5029,11 @@ yy468: } YYDEBUG(469, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1441 "Zend/zend_language_scanner.l" +#line 1417 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PROTECTED); } -#line 5061 "Zend/zend_language_scanner.c" +#line 5037 "Zend/zend_language_scanner.c" yy470: YYDEBUG(470, *YYCURSOR); yych = *++YYCURSOR; @@ -5087,11 +5063,11 @@ yy474: } YYDEBUG(475, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1437 "Zend/zend_language_scanner.l" +#line 1413 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PRIVATE); } -#line 5095 "Zend/zend_language_scanner.c" +#line 5071 "Zend/zend_language_scanner.c" yy476: YYDEBUG(476, *YYCURSOR); ++YYCURSOR; @@ -5100,11 +5076,11 @@ yy476: } YYDEBUG(477, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1271 "Zend/zend_language_scanner.l" +#line 1247 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PRINT); } -#line 5108 "Zend/zend_language_scanner.c" +#line 5084 "Zend/zend_language_scanner.c" yy478: YYDEBUG(478, *YYCURSOR); yych = *++YYCURSOR; @@ -5129,11 +5105,11 @@ yy481: } YYDEBUG(482, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1263 "Zend/zend_language_scanner.l" +#line 1239 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_GOTO); } -#line 5137 "Zend/zend_language_scanner.c" +#line 5113 "Zend/zend_language_scanner.c" yy483: YYDEBUG(483, *YYCURSOR); yych = *++YYCURSOR; @@ -5157,11 +5133,11 @@ yy486: } YYDEBUG(487, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1409 "Zend/zend_language_scanner.l" +#line 1385 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_GLOBAL); } -#line 5165 "Zend/zend_language_scanner.c" +#line 5141 "Zend/zend_language_scanner.c" yy488: YYDEBUG(488, *YYCURSOR); yych = *++YYCURSOR; @@ -5198,11 +5174,11 @@ yy494: } YYDEBUG(495, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1255 "Zend/zend_language_scanner.l" +#line 1231 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BREAK); } -#line 5206 "Zend/zend_language_scanner.c" +#line 5182 "Zend/zend_language_scanner.c" yy496: YYDEBUG(496, *YYCURSOR); yych = *++YYCURSOR; @@ -5242,11 +5218,11 @@ yy502: } YYDEBUG(503, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1239 "Zend/zend_language_scanner.l" +#line 1215 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SWITCH); } -#line 5250 "Zend/zend_language_scanner.c" +#line 5226 "Zend/zend_language_scanner.c" yy504: YYDEBUG(504, *YYCURSOR); yych = *++YYCURSOR; @@ -5270,11 +5246,11 @@ yy507: } YYDEBUG(508, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1425 "Zend/zend_language_scanner.l" +#line 1401 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_STATIC); } -#line 5278 "Zend/zend_language_scanner.c" +#line 5254 "Zend/zend_language_scanner.c" yy509: YYDEBUG(509, *YYCURSOR); yych = *++YYCURSOR; @@ -5301,11 +5277,11 @@ yy512: } YYDEBUG(513, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1235 "Zend/zend_language_scanner.l" +#line 1211 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_AS); } -#line 5309 "Zend/zend_language_scanner.c" +#line 5285 "Zend/zend_language_scanner.c" yy514: YYDEBUG(514, *YYCURSOR); yych = *++YYCURSOR; @@ -5324,11 +5300,11 @@ yy516: } YYDEBUG(517, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1461 "Zend/zend_language_scanner.l" +#line 1437 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ARRAY); } -#line 5332 "Zend/zend_language_scanner.c" +#line 5308 "Zend/zend_language_scanner.c" yy518: YYDEBUG(518, *YYCURSOR); ++YYCURSOR; @@ -5337,11 +5313,11 @@ yy518: } YYDEBUG(519, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1569 "Zend/zend_language_scanner.l" +#line 1545 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LOGICAL_AND); } -#line 5345 "Zend/zend_language_scanner.c" +#line 5321 "Zend/zend_language_scanner.c" yy520: YYDEBUG(520, *YYCURSOR); yych = *++YYCURSOR; @@ -5375,11 +5351,11 @@ yy525: } YYDEBUG(526, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1429 "Zend/zend_language_scanner.l" +#line 1405 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ABSTRACT); } -#line 5383 "Zend/zend_language_scanner.c" +#line 5359 "Zend/zend_language_scanner.c" yy527: YYDEBUG(527, *YYCURSOR); yych = *++YYCURSOR; @@ -5403,11 +5379,11 @@ yy530: } YYDEBUG(531, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1195 "Zend/zend_language_scanner.l" +#line 1171 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_WHILE); } -#line 5411 "Zend/zend_language_scanner.c" +#line 5387 "Zend/zend_language_scanner.c" yy532: YYDEBUG(532, *YYCURSOR); ++YYCURSOR; @@ -5416,11 +5392,11 @@ yy532: } YYDEBUG(533, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1179 "Zend/zend_language_scanner.l" +#line 1155 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IF); } -#line 5424 "Zend/zend_language_scanner.c" +#line 5400 "Zend/zend_language_scanner.c" yy534: YYDEBUG(534, *YYCURSOR); yych = *++YYCURSOR; @@ -5472,11 +5448,11 @@ yy539: } YYDEBUG(540, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1413 "Zend/zend_language_scanner.l" +#line 1389 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ISSET); } -#line 5480 "Zend/zend_language_scanner.c" +#line 5456 "Zend/zend_language_scanner.c" yy541: YYDEBUG(541, *YYCURSOR); yych = *++YYCURSOR; @@ -5530,11 +5506,11 @@ yy547: yy548: YYDEBUG(548, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1381 "Zend/zend_language_scanner.l" +#line 1357 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INCLUDE); } -#line 5538 "Zend/zend_language_scanner.c" +#line 5514 "Zend/zend_language_scanner.c" yy549: YYDEBUG(549, *YYCURSOR); yych = *++YYCURSOR; @@ -5563,11 +5539,11 @@ yy553: } YYDEBUG(554, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1385 "Zend/zend_language_scanner.l" +#line 1361 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INCLUDE_ONCE); } -#line 5571 "Zend/zend_language_scanner.c" +#line 5547 "Zend/zend_language_scanner.c" yy555: YYDEBUG(555, *YYCURSOR); yych = *++YYCURSOR; @@ -5601,11 +5577,11 @@ yy560: } YYDEBUG(561, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1279 "Zend/zend_language_scanner.l" +#line 1255 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INTERFACE); } -#line 5609 "Zend/zend_language_scanner.c" +#line 5585 "Zend/zend_language_scanner.c" yy562: YYDEBUG(562, *YYCURSOR); yych = *++YYCURSOR; @@ -5655,11 +5631,11 @@ yy568: } YYDEBUG(569, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1405 "Zend/zend_language_scanner.l" +#line 1381 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INSTEADOF); } -#line 5663 "Zend/zend_language_scanner.c" +#line 5639 "Zend/zend_language_scanner.c" yy570: YYDEBUG(570, *YYCURSOR); yych = *++YYCURSOR; @@ -5688,11 +5664,11 @@ yy574: } YYDEBUG(575, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1231 "Zend/zend_language_scanner.l" +#line 1207 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INSTANCEOF); } -#line 5696 "Zend/zend_language_scanner.c" +#line 5672 "Zend/zend_language_scanner.c" yy576: YYDEBUG(576, *YYCURSOR); yych = *++YYCURSOR; @@ -5736,11 +5712,11 @@ yy583: } YYDEBUG(584, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1291 "Zend/zend_language_scanner.l" +#line 1267 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IMPLEMENTS); } -#line 5744 "Zend/zend_language_scanner.c" +#line 5720 "Zend/zend_language_scanner.c" yy585: YYDEBUG(585, *YYCURSOR); yych = *++YYCURSOR; @@ -5768,11 +5744,11 @@ yy586: } YYDEBUG(588, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1163 "Zend/zend_language_scanner.l" +#line 1139 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_TRY); } -#line 5776 "Zend/zend_language_scanner.c" +#line 5752 "Zend/zend_language_scanner.c" yy589: YYDEBUG(589, *YYCURSOR); yych = *++YYCURSOR; @@ -5791,11 +5767,11 @@ yy591: } YYDEBUG(592, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1283 "Zend/zend_language_scanner.l" +#line 1259 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_TRAIT); } -#line 5799 "Zend/zend_language_scanner.c" +#line 5775 "Zend/zend_language_scanner.c" yy593: YYDEBUG(593, *YYCURSOR); yych = *++YYCURSOR; @@ -5814,11 +5790,11 @@ yy595: } YYDEBUG(596, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1175 "Zend/zend_language_scanner.l" +#line 1151 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_THROW); } -#line 5822 "Zend/zend_language_scanner.c" +#line 5798 "Zend/zend_language_scanner.c" yy597: YYDEBUG(597, *YYCURSOR); yych = *++YYCURSOR; @@ -5851,11 +5827,11 @@ yy600: yy601: YYDEBUG(601, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1159 "Zend/zend_language_scanner.l" +#line 1135 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_YIELD); } -#line 5859 "Zend/zend_language_scanner.c" +#line 5835 "Zend/zend_language_scanner.c" yy602: YYDEBUG(602, *YYCURSOR); ++YYCURSOR; @@ -5897,12 +5873,12 @@ yy607: ++YYCURSOR; YYDEBUG(608, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1154 "Zend/zend_language_scanner.l" +#line 1130 "Zend/zend_language_scanner.l" { HANDLE_NEWLINES(yytext, yyleng); RETURN_TOKEN(T_YIELD_FROM); } -#line 5906 "Zend/zend_language_scanner.c" +#line 5882 "Zend/zend_language_scanner.c" yy609: YYDEBUG(609, *YYCURSOR); yych = *++YYCURSOR; @@ -5963,11 +5939,11 @@ yy615: yy616: YYDEBUG(616, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1389 "Zend/zend_language_scanner.l" +#line 1365 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_REQUIRE); } -#line 5971 "Zend/zend_language_scanner.c" +#line 5947 "Zend/zend_language_scanner.c" yy617: YYDEBUG(617, *YYCURSOR); yych = *++YYCURSOR; @@ -5996,11 +5972,11 @@ yy621: } YYDEBUG(622, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1393 "Zend/zend_language_scanner.l" +#line 1369 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_REQUIRE_ONCE); } -#line 6004 "Zend/zend_language_scanner.c" +#line 5980 "Zend/zend_language_scanner.c" yy623: YYDEBUG(623, *YYCURSOR); yych = *++YYCURSOR; @@ -6019,11 +5995,11 @@ yy625: } YYDEBUG(626, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1150 "Zend/zend_language_scanner.l" +#line 1126 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_RETURN); } -#line 6027 "Zend/zend_language_scanner.c" +#line 6003 "Zend/zend_language_scanner.c" yy627: YYDEBUG(627, *YYCURSOR); yych = *++YYCURSOR; @@ -6113,11 +6089,11 @@ yy636: } YYDEBUG(637, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1259 "Zend/zend_language_scanner.l" +#line 1235 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CONTINUE); } -#line 6121 "Zend/zend_language_scanner.c" +#line 6097 "Zend/zend_language_scanner.c" yy638: YYDEBUG(638, *YYCURSOR); ++YYCURSOR; @@ -6126,11 +6102,11 @@ yy638: } YYDEBUG(639, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1146 "Zend/zend_language_scanner.l" +#line 1122 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CONST); } -#line 6134 "Zend/zend_language_scanner.c" +#line 6110 "Zend/zend_language_scanner.c" yy640: YYDEBUG(640, *YYCURSOR); yych = *++YYCURSOR; @@ -6155,11 +6131,11 @@ yy643: } YYDEBUG(644, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1341 "Zend/zend_language_scanner.l" +#line 1317 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CLONE); } -#line 6163 "Zend/zend_language_scanner.c" +#line 6139 "Zend/zend_language_scanner.c" yy645: YYDEBUG(645, *YYCURSOR); yych = *++YYCURSOR; @@ -6173,11 +6149,11 @@ yy646: } YYDEBUG(647, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1275 "Zend/zend_language_scanner.l" +#line 1251 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CLASS); } -#line 6181 "Zend/zend_language_scanner.c" +#line 6157 "Zend/zend_language_scanner.c" yy648: YYDEBUG(648, *YYCURSOR); yych = *++YYCURSOR; @@ -6223,11 +6199,11 @@ yy655: } YYDEBUG(656, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1465 "Zend/zend_language_scanner.l" +#line 1441 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CALLABLE); } -#line 6231 "Zend/zend_language_scanner.c" +#line 6207 "Zend/zend_language_scanner.c" yy657: YYDEBUG(657, *YYCURSOR); ++YYCURSOR; @@ -6236,11 +6212,11 @@ yy657: } YYDEBUG(658, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1247 "Zend/zend_language_scanner.l" +#line 1223 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CASE); } -#line 6244 "Zend/zend_language_scanner.c" +#line 6220 "Zend/zend_language_scanner.c" yy659: YYDEBUG(659, *YYCURSOR); yych = *++YYCURSOR; @@ -6254,11 +6230,11 @@ yy660: } YYDEBUG(661, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1167 "Zend/zend_language_scanner.l" +#line 1143 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CATCH); } -#line 6262 "Zend/zend_language_scanner.c" +#line 6238 "Zend/zend_language_scanner.c" yy662: YYDEBUG(662, *YYCURSOR); yych = *++YYCURSOR; @@ -6309,11 +6285,11 @@ yy670: } YYDEBUG(671, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1142 "Zend/zend_language_scanner.l" +#line 1118 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FUNCTION); } -#line 6317 "Zend/zend_language_scanner.c" +#line 6293 "Zend/zend_language_scanner.c" yy672: YYDEBUG(672, *YYCURSOR); ++YYCURSOR; @@ -6337,11 +6313,11 @@ yy672: yy673: YYDEBUG(673, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1207 "Zend/zend_language_scanner.l" +#line 1183 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FOR); } -#line 6345 "Zend/zend_language_scanner.c" +#line 6321 "Zend/zend_language_scanner.c" yy674: YYDEBUG(674, *YYCURSOR); yych = *++YYCURSOR; @@ -6365,11 +6341,11 @@ yy677: } YYDEBUG(678, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1215 "Zend/zend_language_scanner.l" +#line 1191 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FOREACH); } -#line 6373 "Zend/zend_language_scanner.c" +#line 6349 "Zend/zend_language_scanner.c" yy679: YYDEBUG(679, *YYCURSOR); yych = *++YYCURSOR; @@ -6403,11 +6379,11 @@ yy681: yy682: YYDEBUG(682, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1433 "Zend/zend_language_scanner.l" +#line 1409 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FINAL); } -#line 6411 "Zend/zend_language_scanner.c" +#line 6387 "Zend/zend_language_scanner.c" yy683: YYDEBUG(683, *YYCURSOR); yych = *++YYCURSOR; @@ -6421,11 +6397,11 @@ yy684: } YYDEBUG(685, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1171 "Zend/zend_language_scanner.l" +#line 1147 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FINALLY); } -#line 6429 "Zend/zend_language_scanner.c" +#line 6405 "Zend/zend_language_scanner.c" yy686: YYDEBUG(686, *YYCURSOR); yych = *++YYCURSOR; @@ -6456,11 +6432,11 @@ yy688: } YYDEBUG(689, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1203 "Zend/zend_language_scanner.l" +#line 1179 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DO); } -#line 6464 "Zend/zend_language_scanner.c" +#line 6440 "Zend/zend_language_scanner.c" yy690: YYDEBUG(690, *YYCURSOR); ++YYCURSOR; @@ -6469,11 +6445,11 @@ yy690: } YYDEBUG(691, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1138 "Zend/zend_language_scanner.l" +#line 1114 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EXIT); } -#line 6477 "Zend/zend_language_scanner.c" +#line 6453 "Zend/zend_language_scanner.c" yy692: YYDEBUG(692, *YYCURSOR); yych = *++YYCURSOR; @@ -6508,11 +6484,11 @@ yy697: } YYDEBUG(698, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1251 "Zend/zend_language_scanner.l" +#line 1227 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DEFAULT); } -#line 6516 "Zend/zend_language_scanner.c" +#line 6492 "Zend/zend_language_scanner.c" yy699: YYDEBUG(699, *YYCURSOR); yych = *++YYCURSOR; @@ -6536,11 +6512,11 @@ yy702: } YYDEBUG(703, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1223 "Zend/zend_language_scanner.l" +#line 1199 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DECLARE); } -#line 6544 "Zend/zend_language_scanner.c" +#line 6520 "Zend/zend_language_scanner.c" yy704: YYDEBUG(704, *YYCURSOR); yych = *++YYCURSOR; @@ -6620,11 +6596,11 @@ yy715: } YYDEBUG(716, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1287 "Zend/zend_language_scanner.l" +#line 1263 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EXTENDS); } -#line 6628 "Zend/zend_language_scanner.c" +#line 6604 "Zend/zend_language_scanner.c" yy717: YYDEBUG(717, *YYCURSOR); ++YYCURSOR; @@ -6633,11 +6609,11 @@ yy717: } YYDEBUG(718, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1134 "Zend/zend_language_scanner.l" +#line 1110 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EXIT); } -#line 6641 "Zend/zend_language_scanner.c" +#line 6617 "Zend/zend_language_scanner.c" yy719: YYDEBUG(719, *YYCURSOR); yych = *++YYCURSOR; @@ -6651,11 +6627,11 @@ yy720: } YYDEBUG(721, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1377 "Zend/zend_language_scanner.l" +#line 1353 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EVAL); } -#line 6659 "Zend/zend_language_scanner.c" +#line 6635 "Zend/zend_language_scanner.c" yy722: YYDEBUG(722, *YYCURSOR); yych = *++YYCURSOR; @@ -6725,11 +6701,11 @@ yy731: } YYDEBUG(732, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1199 "Zend/zend_language_scanner.l" +#line 1175 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDWHILE); } -#line 6733 "Zend/zend_language_scanner.c" +#line 6709 "Zend/zend_language_scanner.c" yy733: YYDEBUG(733, *YYCURSOR); yych = *++YYCURSOR; @@ -6758,11 +6734,11 @@ yy737: } YYDEBUG(738, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1243 "Zend/zend_language_scanner.l" +#line 1219 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDSWITCH); } -#line 6766 "Zend/zend_language_scanner.c" +#line 6742 "Zend/zend_language_scanner.c" yy739: YYDEBUG(739, *YYCURSOR); ++YYCURSOR; @@ -6771,11 +6747,11 @@ yy739: } YYDEBUG(740, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1187 "Zend/zend_language_scanner.l" +#line 1163 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDIF); } -#line 6779 "Zend/zend_language_scanner.c" +#line 6755 "Zend/zend_language_scanner.c" yy741: YYDEBUG(741, *YYCURSOR); yych = *++YYCURSOR; @@ -6804,11 +6780,11 @@ yy742: yy743: YYDEBUG(743, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1211 "Zend/zend_language_scanner.l" +#line 1187 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDFOR); } -#line 6812 "Zend/zend_language_scanner.c" +#line 6788 "Zend/zend_language_scanner.c" yy744: YYDEBUG(744, *YYCURSOR); yych = *++YYCURSOR; @@ -6832,11 +6808,11 @@ yy747: } YYDEBUG(748, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1219 "Zend/zend_language_scanner.l" +#line 1195 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDFOREACH); } -#line 6840 "Zend/zend_language_scanner.c" +#line 6816 "Zend/zend_language_scanner.c" yy749: YYDEBUG(749, *YYCURSOR); yych = *++YYCURSOR; @@ -6870,11 +6846,11 @@ yy754: } YYDEBUG(755, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1227 "Zend/zend_language_scanner.l" +#line 1203 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDDECLARE); } -#line 6878 "Zend/zend_language_scanner.c" +#line 6854 "Zend/zend_language_scanner.c" yy756: YYDEBUG(756, *YYCURSOR); yych = *++YYCURSOR; @@ -6893,11 +6869,11 @@ yy758: } YYDEBUG(759, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1417 "Zend/zend_language_scanner.l" +#line 1393 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EMPTY); } -#line 6901 "Zend/zend_language_scanner.c" +#line 6877 "Zend/zend_language_scanner.c" yy760: YYDEBUG(760, *YYCURSOR); yych = *++YYCURSOR; @@ -6926,11 +6902,11 @@ yy761: yy762: YYDEBUG(762, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1191 "Zend/zend_language_scanner.l" +#line 1167 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ELSE); } -#line 6934 "Zend/zend_language_scanner.c" +#line 6910 "Zend/zend_language_scanner.c" yy763: YYDEBUG(763, *YYCURSOR); yych = *++YYCURSOR; @@ -6944,11 +6920,11 @@ yy764: } YYDEBUG(765, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1183 "Zend/zend_language_scanner.l" +#line 1159 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ELSEIF); } -#line 6952 "Zend/zend_language_scanner.c" +#line 6928 "Zend/zend_language_scanner.c" yy766: YYDEBUG(766, *YYCURSOR); yych = *++YYCURSOR; @@ -6962,11 +6938,11 @@ yy767: } YYDEBUG(768, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1267 "Zend/zend_language_scanner.l" +#line 1243 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ECHO); } -#line 6970 "Zend/zend_language_scanner.c" +#line 6946 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_LOOKING_FOR_PROPERTY: @@ -7039,12 +7015,12 @@ yy771: yy772: YYDEBUG(772, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1300 "Zend/zend_language_scanner.l" +#line 1276 "Zend/zend_language_scanner.l" { HANDLE_NEWLINES(yytext, yyleng); RETURN_TOKEN(T_WHITESPACE); } -#line 7048 "Zend/zend_language_scanner.c" +#line 7024 "Zend/zend_language_scanner.c" yy773: YYDEBUG(773, *YYCURSOR); ++YYCURSOR; @@ -7052,13 +7028,13 @@ yy773: yy774: YYDEBUG(774, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1315 "Zend/zend_language_scanner.l" +#line 1291 "Zend/zend_language_scanner.l" { yyless(0); yy_pop_state(); goto restart; } -#line 7062 "Zend/zend_language_scanner.c" +#line 7038 "Zend/zend_language_scanner.c" yy775: YYDEBUG(775, *YYCURSOR); ++YYCURSOR; @@ -7067,13 +7043,13 @@ yy775: yy776: YYDEBUG(776, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1309 "Zend/zend_language_scanner.l" +#line 1285 "Zend/zend_language_scanner.l" { yy_pop_state(); zend_copy_value(zendlval, yytext, yyleng); RETURN_TOKEN(T_STRING); } -#line 7077 "Zend/zend_language_scanner.c" +#line 7053 "Zend/zend_language_scanner.c" yy777: YYDEBUG(777, *YYCURSOR); yych = *++YYCURSOR; @@ -7094,11 +7070,11 @@ yy780: ++YYCURSOR; YYDEBUG(781, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1305 "Zend/zend_language_scanner.l" +#line 1281 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_OBJECT_OPERATOR); } -#line 7102 "Zend/zend_language_scanner.c" +#line 7078 "Zend/zend_language_scanner.c" yy782: YYDEBUG(782, *YYCURSOR); ++YYCURSOR; @@ -7183,14 +7159,14 @@ yy786: yy787: YYDEBUG(787, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1620 "Zend/zend_language_scanner.l" +#line 1596 "Zend/zend_language_scanner.l" { yyless(0); yy_pop_state(); yy_push_state(ST_IN_SCRIPTING); goto restart; } -#line 7194 "Zend/zend_language_scanner.c" +#line 7170 "Zend/zend_language_scanner.c" yy788: YYDEBUG(788, *YYCURSOR); yych = *++YYCURSOR; @@ -7215,7 +7191,7 @@ yy792: ++YYCURSOR; YYDEBUG(793, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1611 "Zend/zend_language_scanner.l" +#line 1587 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); zend_copy_value(zendlval, yytext, yyleng); @@ -7223,7 +7199,7 @@ yy792: yy_push_state(ST_IN_SCRIPTING); RETURN_TOKEN(T_STRING_VARNAME); } -#line 7227 "Zend/zend_language_scanner.c" +#line 7203 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_NOWDOC: @@ -7234,7 +7210,7 @@ yyc_ST_NOWDOC: ++YYCURSOR; YYDEBUG(797, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2339 "Zend/zend_language_scanner.l" +#line 2315 "Zend/zend_language_scanner.l" { int newline = 0; @@ -7290,7 +7266,7 @@ nowdoc_scan_done: HANDLE_NEWLINES(yytext, yyleng - newline); RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE); } -#line 7294 "Zend/zend_language_scanner.c" +#line 7270 "Zend/zend_language_scanner.c" /* *********************************** */ yyc_ST_VAR_OFFSET: { @@ -7397,7 +7373,7 @@ yy800: yy801: YYDEBUG(801, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1728 "Zend/zend_language_scanner.l" +#line 1704 "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; @@ -7413,7 +7389,7 @@ string: } RETURN_TOKEN(T_NUM_STRING); } -#line 7417 "Zend/zend_language_scanner.c" +#line 7393 "Zend/zend_language_scanner.c" yy802: YYDEBUG(802, *YYCURSOR); yych = *++YYCURSOR; @@ -7433,23 +7409,23 @@ yy803: yy804: YYDEBUG(804, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1888 "Zend/zend_language_scanner.l" +#line 1864 "Zend/zend_language_scanner.l" { /* Only '[' can be valid, but returning other tokens will allow a more explicit parse error */ RETURN_TOKEN(yytext[0]); } -#line 7442 "Zend/zend_language_scanner.c" +#line 7418 "Zend/zend_language_scanner.c" yy805: YYDEBUG(805, *YYCURSOR); ++YYCURSOR; YYDEBUG(806, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1883 "Zend/zend_language_scanner.l" +#line 1859 "Zend/zend_language_scanner.l" { yy_pop_state(); RETURN_TOKEN(']'); } -#line 7453 "Zend/zend_language_scanner.c" +#line 7429 "Zend/zend_language_scanner.c" yy807: YYDEBUG(807, *YYCURSOR); yych = *++YYCURSOR; @@ -7459,7 +7435,7 @@ yy808: ++YYCURSOR; YYDEBUG(809, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1893 "Zend/zend_language_scanner.l" +#line 1869 "Zend/zend_language_scanner.l" { /* Invalid rule to return a more explicit parse error with proper line number */ yyless(0); @@ -7467,7 +7443,7 @@ yy808: ZVAL_NULL(zendlval); RETURN_TOKEN(T_ENCAPSED_AND_WHITESPACE); } -#line 7471 "Zend/zend_language_scanner.c" +#line 7447 "Zend/zend_language_scanner.c" yy810: YYDEBUG(810, *YYCURSOR); ++YYCURSOR; @@ -7476,18 +7452,18 @@ yy810: yy811: YYDEBUG(811, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1901 "Zend/zend_language_scanner.l" +#line 1877 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, yytext, yyleng); RETURN_TOKEN(T_STRING); } -#line 7485 "Zend/zend_language_scanner.c" +#line 7461 "Zend/zend_language_scanner.c" yy812: YYDEBUG(812, *YYCURSOR); ++YYCURSOR; YYDEBUG(813, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2396 "Zend/zend_language_scanner.l" +#line 2372 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -7496,7 +7472,7 @@ yy812: zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE); goto restart; } -#line 7500 "Zend/zend_language_scanner.c" +#line 7476 "Zend/zend_language_scanner.c" yy814: YYDEBUG(814, *YYCURSOR); ++YYCURSOR; @@ -7532,12 +7508,12 @@ yy816: yy818: YYDEBUG(818, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1878 "Zend/zend_language_scanner.l" +#line 1854 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); RETURN_TOKEN(T_VARIABLE); } -#line 7541 "Zend/zend_language_scanner.c" +#line 7517 "Zend/zend_language_scanner.c" yy819: YYDEBUG(819, *YYCURSOR); ++YYCURSOR; @@ -7577,12 +7553,12 @@ yy824: yy826: YYDEBUG(826, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1744 "Zend/zend_language_scanner.l" +#line 1720 "Zend/zend_language_scanner.l" { /* Offset must be treated as a string */ ZVAL_STRINGL(zendlval, yytext, yyleng); RETURN_TOKEN(T_NUM_STRING); } -#line 7586 "Zend/zend_language_scanner.c" +#line 7562 "Zend/zend_language_scanner.c" yy827: YYDEBUG(827, *YYCURSOR); ++YYCURSOR; @@ -7605,6 +7581,6 @@ yy829: goto yy826; } } -#line 2405 "Zend/zend_language_scanner.l" +#line 2381 "Zend/zend_language_scanner.l" } diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 8c5a4e47f5..bc0b92eb1a 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -568,6 +568,48 @@ ZEND_API int open_file_for_scanning(zend_file_handle *file_handle) } END_EXTERN_C() +static zend_op_array *zend_compile(int type) +{ + zend_op_array *op_array = NULL; + zend_bool original_in_compilation = CG(in_compilation); + + CG(in_compilation) = 1; + CG(ast) = NULL; + CG(ast_arena) = zend_arena_create(1024 * 32); + + if (!zendparse()) { + zend_file_context original_file_context; + zend_oparray_context original_oparray_context; + zend_op_array *original_active_op_array = CG(active_op_array); + + op_array = emalloc(sizeof(zend_op_array)); + init_op_array(op_array, type, INITIAL_OP_ARRAY_SIZE); + CG(active_op_array) = op_array; + + if (zend_ast_process) { + zend_ast_process(CG(ast)); + } + + zend_file_context_begin(&original_file_context); + zend_oparray_context_begin(&original_oparray_context); + zend_compile_top_stmt(CG(ast)); + zend_emit_final_return(type == ZEND_USER_FUNCTION); + op_array->line_start = 1; + op_array->line_end = CG(zend_lineno); + pass_two(op_array); + zend_oparray_context_end(&original_oparray_context); + zend_file_context_end(&original_file_context); + + CG(active_op_array) = original_active_op_array; + } + + zend_ast_destroy(CG(ast)); + zend_arena_destroy(CG(ast_arena)); + + CG(in_compilation) = original_in_compilation; + + return op_array; +} ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type) { @@ -583,41 +625,7 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type) zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename); } } else { - zend_bool original_in_compilation = CG(in_compilation); - CG(in_compilation) = 1; - - CG(ast) = NULL; - CG(ast_arena) = zend_arena_create(1024 * 32); - if (!zendparse()) { - zval retval_zv; - zend_file_context original_file_context; - zend_oparray_context original_oparray_context; - zend_op_array *original_active_op_array = CG(active_op_array); - op_array = emalloc(sizeof(zend_op_array)); - init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE); - CG(active_op_array) = op_array; - ZVAL_LONG(&retval_zv, 1); - - if (zend_ast_process) { - zend_ast_process(CG(ast)); - } - - zend_file_context_begin(&original_file_context); - zend_oparray_context_begin(&original_oparray_context); - zend_compile_top_stmt(CG(ast)); - zend_emit_final_return(&retval_zv); - op_array->line_start = 1; - op_array->line_end = CG(zend_lineno); - pass_two(op_array); - zend_oparray_context_end(&original_oparray_context); - zend_file_context_end(&original_file_context); - - CG(active_op_array) = original_active_op_array; - } - - zend_ast_destroy(CG(ast)); - zend_arena_destroy(CG(ast_arena)); - CG(in_compilation) = original_in_compilation; + op_array = zend_compile(ZEND_USER_FUNCTION); } zend_restore_lexical_state(&original_lex_state); @@ -732,13 +740,11 @@ ZEND_API size_t zend_get_scanned_file_offset(void) return offset; } - zend_op_array *compile_string(zval *source_string, char *filename) { zend_lex_state original_lex_state; zend_op_array *op_array = NULL; zval tmp; - zend_bool original_in_compilation = CG(in_compilation); if (Z_STRLEN_P(source_string)==0) { return NULL; @@ -748,45 +754,15 @@ zend_op_array *compile_string(zval *source_string, char *filename) convert_to_string(&tmp); source_string = &tmp; - CG(in_compilation) = 1; zend_save_lexical_state(&original_lex_state); if (zend_prepare_string_for_scanning(source_string, filename) == SUCCESS) { - CG(ast) = NULL; - CG(ast_arena) = zend_arena_create(1024 * 32); BEGIN(ST_IN_SCRIPTING); - - if (!zendparse()) { - zend_file_context original_file_context; - zend_oparray_context original_oparray_context; - zend_op_array *original_active_op_array = CG(active_op_array); - op_array = emalloc(sizeof(zend_op_array)); - init_op_array(op_array, ZEND_EVAL_CODE, INITIAL_OP_ARRAY_SIZE); - CG(active_op_array) = op_array; - - if (zend_ast_process) { - zend_ast_process(CG(ast)); - } - - zend_file_context_begin(&original_file_context); - zend_oparray_context_begin(&original_oparray_context); - zend_compile_top_stmt(CG(ast)); - zend_emit_final_return(NULL); - op_array->line_start = 1; - op_array->line_end = CG(zend_lineno); - pass_two(op_array); - zend_oparray_context_end(&original_oparray_context); - zend_file_context_end(&original_file_context); - - CG(active_op_array) = original_active_op_array; - } - - zend_ast_destroy(CG(ast)); - zend_arena_destroy(CG(ast_arena)); + op_array = zend_compile(ZEND_EVAL_CODE); } zend_restore_lexical_state(&original_lex_state); zval_dtor(&tmp); - CG(in_compilation) = original_in_compilation; + return op_array; } diff --git a/Zend/zend_modules.h b/Zend/zend_modules.h index 07e1937e03..b388b7cb1a 100644 --- a/Zend/zend_modules.h +++ b/Zend/zend_modules.h @@ -33,7 +33,7 @@ #define ZEND_MODULE_INFO_FUNC_ARGS zend_module_entry *zend_module #define ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU zend_module -#define ZEND_MODULE_API_NO 20151012 +#define ZEND_MODULE_API_NO 20160303 #ifdef ZTS #define USING_ZTS 1 #else diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 2cf32b9c0a..6c1488ad0c 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -78,9 +78,9 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz op_array->scope = NULL; op_array->prototype = NULL; - op_array->brk_cont_array = NULL; + op_array->live_range = NULL; op_array->try_catch_array = NULL; - op_array->last_brk_cont = 0; + op_array->last_live_range = 0; op_array->static_variables = NULL; op_array->last_try_catch = 0; @@ -287,7 +287,19 @@ ZEND_API void destroy_zend_class(zval *zv) zend_hash_destroy(&ce->properties_info); zend_string_release(ce->name); zend_hash_destroy(&ce->function_table); - zend_hash_destroy(&ce->constants_table); + if (zend_hash_num_elements(&ce->constants_table)) { + zend_class_constant *c; + + ZEND_HASH_FOREACH_PTR(&ce->constants_table, c) { + if (c->ce == ce) { + zval_ptr_dtor(&c->value); + if (c->doc_comment) { + zend_string_release(c->doc_comment); + } + } + } ZEND_HASH_FOREACH_END(); + zend_hash_destroy(&ce->constants_table); + } if (ce->num_interfaces > 0 && ce->interfaces) { efree(ce->interfaces); } @@ -322,7 +334,17 @@ ZEND_API void destroy_zend_class(zval *zv) zend_hash_destroy(&ce->properties_info); zend_string_release(ce->name); zend_hash_destroy(&ce->function_table); - zend_hash_destroy(&ce->constants_table); + if (zend_hash_num_elements(&ce->constants_table)) { + 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); + } + } ZEND_HASH_FOREACH_END(); + zend_hash_destroy(&ce->constants_table); + } if (ce->num_interfaces > 0) { free(ce->interfaces); } @@ -387,8 +409,8 @@ ZEND_API void destroy_op_array(zend_op_array *op_array) if (op_array->doc_comment) { zend_string_release(op_array->doc_comment); } - if (op_array->brk_cont_array) { - efree(op_array->brk_cont_array); + if (op_array->live_range) { + efree(op_array->live_range); } if (op_array->try_catch_array) { efree(op_array->try_catch_array); @@ -450,11 +472,11 @@ int get_next_op_number(zend_op_array *op_array) return op_array->last; } -zend_brk_cont_element *get_next_brk_cont_element(zend_op_array *op_array) +zend_brk_cont_element *get_next_brk_cont_element(void) { - op_array->last_brk_cont++; - op_array->brk_cont_array = erealloc(op_array->brk_cont_array, sizeof(zend_brk_cont_element)*op_array->last_brk_cont); - return &op_array->brk_cont_array[op_array->last_brk_cont-1]; + CG(context).last_brk_cont++; + CG(context).brk_cont_array = erealloc(CG(context).brk_cont_array, sizeof(zend_brk_cont_element) * CG(context).last_brk_cont); + return &CG(context).brk_cont_array[CG(context).last_brk_cont-1]; } static void zend_update_extended_info(zend_op_array *op_array) @@ -515,48 +537,52 @@ static void zend_check_finally_breakout(zend_op_array *op_array, uint32_t op_num static void zend_resolve_fast_call(zend_op_array *op_array, uint32_t op_num) { int i; - uint32_t finally_op_num = 0; + uint32_t finally_num = (uint32_t)-1; for (i = 0; i < op_array->last_try_catch; i++) { if (op_num >= op_array->try_catch_array[i].finally_op && op_num < op_array->try_catch_array[i].finally_end) { - finally_op_num = op_array->try_catch_array[i].finally_op; + finally_num = i; } } - if (finally_op_num) { + if (finally_num != (uint32_t)-1) { /* Must be ZEND_FAST_CALL */ - ZEND_ASSERT(op_array->opcodes[finally_op_num - 2].opcode == ZEND_FAST_CALL); + ZEND_ASSERT(op_array->opcodes[op_array->try_catch_array[finally_num].finally_op - 2].opcode == ZEND_FAST_CALL); op_array->opcodes[op_num].extended_value = ZEND_FAST_CALL_FROM_FINALLY; - op_array->opcodes[op_num].op2.opline_num = finally_op_num - 2; + op_array->opcodes[op_num].op2.num = finally_num; } } static void zend_resolve_finally_ret(zend_op_array *op_array, uint32_t op_num) { int i; - uint32_t catch_op_num = 0, finally_op_num = 0; + uint32_t finally_num = (uint32_t)-1; + uint32_t catch_num = (uint32_t)-1; for (i = 0; i < op_array->last_try_catch; i++) { if (op_array->try_catch_array[i].try_op > op_num) { break; } if (op_num < op_array->try_catch_array[i].finally_op) { - finally_op_num = op_array->try_catch_array[i].finally_op; + finally_num = i; } if (op_num < op_array->try_catch_array[i].catch_op) { - catch_op_num = op_array->try_catch_array[i].catch_op; + catch_num = i; } } - if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) { + if (finally_num != (uint32_t)-1 && + (catch_num == (uint32_t)-1 || + op_array->try_catch_array[catch_num].catch_op >= + op_array->try_catch_array[finally_num].finally_op)) { /* in case of unhandled exception return to upward finally block */ op_array->opcodes[op_num].extended_value = ZEND_FAST_RET_TO_FINALLY; - op_array->opcodes[op_num].op2.opline_num = finally_op_num; - } else if (catch_op_num) { + op_array->opcodes[op_num].op2.num = finally_num; + } else if (catch_num != (uint32_t)-1) { /* in case of unhandled exception return to upward catch block */ op_array->opcodes[op_num].extended_value = ZEND_FAST_RET_TO_CATCH; - op_array->opcodes[op_num].op2.opline_num = catch_op_num; + op_array->opcodes[op_num].op2.num = catch_num; } } @@ -565,7 +591,7 @@ static uint32_t zend_get_brk_cont_target(const zend_op_array *op_array, const ze int array_offset = opline->op1.num; zend_brk_cont_element *jmp_to; do { - jmp_to = &op_array->brk_cont_array[array_offset]; + jmp_to = &CG(context).brk_cont_array[array_offset]; if (nest_levels > 1) { array_offset = jmp_to->parent; } @@ -614,13 +640,6 @@ ZEND_API int pass_two(zend_op_array *op_array) case ZEND_FAST_RET: zend_resolve_finally_ret(op_array, opline - op_array->opcodes); break; - case ZEND_DECLARE_ANON_INHERITED_CLASS: - ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1); - /* break omitted intentionally */ - case ZEND_DECLARE_INHERITED_CLASS: - case ZEND_DECLARE_INHERITED_CLASS_DELAYED: - opline->extended_value = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->extended_value); - break; case ZEND_BRK: case ZEND_CONT: { @@ -642,7 +661,6 @@ ZEND_API int pass_two(zend_op_array *op_array) } /* break omitted intentionally */ case ZEND_JMP: - case ZEND_DECLARE_ANON_CLASS: ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1); break; case ZEND_JMPZNZ: @@ -655,14 +673,29 @@ ZEND_API int pass_two(zend_op_array *op_array) case ZEND_JMPNZ_EX: case ZEND_JMP_SET: case ZEND_COALESCE: - case ZEND_NEW: case ZEND_FE_RESET_R: case ZEND_FE_RESET_RW: + ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op2); + break; case ZEND_ASSERT_CHECK: + { + /* If result of assert is unused, result of check is unused as well */ + zend_op *call = &op_array->opcodes[opline->op2.opline_num - 1]; + if (call->opcode == ZEND_EXT_FCALL_END) { + call--; + } + if (call->result_type == IS_UNUSED) { + opline->result_type = IS_UNUSED; + } ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op2); break; + } + case ZEND_DECLARE_ANON_CLASS: + case ZEND_DECLARE_ANON_INHERITED_CLASS: + case ZEND_CATCH: case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: + /* absolute index to relative offset */ opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value); break; case ZEND_VERIFY_RETURN_TYPE: @@ -702,6 +735,16 @@ ZEND_API int pass_two(zend_op_array *op_array) opline++; } + if (op_array->live_range) { + uint32_t i; + + for (i = 0; i < op_array->last_live_range; i++) { + op_array->live_range[i].var = + (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + (op_array->live_range[i].var / sizeof(zval))) | + (op_array->live_range[i].var & ZEND_LIVE_MASK); + } + } + op_array->fn_flags |= ZEND_ACC_DONE_PASS_TWO; return 0; } diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 50557e56d8..1710ba44dd 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -147,7 +147,7 @@ static zend_always_inline void zend_unwrap_reference(zval *op) /* {{{ */ } /* }}} */ -ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */ +void ZEND_FASTCALL _convert_scalar_to_number(zval *op, zend_bool silent) /* {{{ */ { try_again: switch (Z_TYPE_P(op)) { @@ -159,8 +159,11 @@ try_again: zend_string *str; str = Z_STR_P(op); - if ((Z_TYPE_INFO_P(op)=is_numeric_string(ZSTR_VAL(str), ZSTR_LEN(str), &Z_LVAL_P(op), &Z_DVAL_P(op), 1)) == 0) { + if ((Z_TYPE_INFO_P(op)=is_numeric_string(ZSTR_VAL(str), ZSTR_LEN(str), &Z_LVAL_P(op), &Z_DVAL_P(op), silent ? 1 : -1)) == 0) { ZVAL_LONG(op, 0); + if (!silent) { + zend_error(E_WARNING, "A non-numeric value encountered"); + } } zend_string_release(str); break; @@ -186,18 +189,27 @@ try_again: } /* }}} */ +ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */ +{ + _convert_scalar_to_number(op, 1); +} +/* }}} */ + /* {{{ zendi_convert_scalar_to_number */ -#define zendi_convert_scalar_to_number(op, holder, result) \ +#define zendi_convert_scalar_to_number(op, holder, result, silent) \ if (op==result) { \ if (Z_TYPE_P(op) != IS_LONG) { \ - convert_scalar_to_number(op); \ + _convert_scalar_to_number(op, silent); \ } \ } else { \ switch (Z_TYPE_P(op)) { \ case IS_STRING: \ { \ - if ((Z_TYPE_INFO(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), 1)) == 0) { \ + if ((Z_TYPE_INFO(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), silent ? 1 : -1)) == 0) { \ ZVAL_LONG(&(holder), 0); \ + if (!silent) { \ + zend_error(E_WARNING, "A non-numeric value encountered"); \ + } \ } \ (op) = &(holder); \ break; \ @@ -258,7 +270,7 @@ try_again: } \ } \ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(op, op_func); \ - op1_lval = _zval_get_long_func(op1); \ + op1_lval = _zval_get_long_func_noisy(op1); \ } else { \ op1_lval = Z_LVAL_P(op1); \ } \ @@ -273,7 +285,7 @@ try_again: } \ } \ ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(op); \ - op2_lval = _zval_get_long_func(op2); \ + op2_lval = _zval_get_long_func_noisy(op2); \ } else { \ op2_lval = Z_LVAL_P(op2); \ } \ @@ -313,8 +325,11 @@ try_again: case IS_STRING: { zend_string *str = Z_STR_P(op); - - ZVAL_LONG(op, ZEND_STRTOL(ZSTR_VAL(str), NULL, base)); + if (base == 10) { + ZVAL_LONG(op, zval_get_long(op)); + } else { + ZVAL_LONG(op, ZEND_STRTOL(ZSTR_VAL(str), NULL, base)); + } zend_string_release(str); } break; @@ -728,7 +743,7 @@ ZEND_API void multi_convert_to_string_ex(int argc, ...) /* {{{ */ } /* }}} */ -ZEND_API zend_long ZEND_FASTCALL _zval_get_long_func(zval *op) /* {{{ */ +static zend_always_inline zend_long ZEND_FASTCALL _zval_get_long_func_ex(zval *op, zend_bool silent) /* {{{ */ { try_again: switch (Z_TYPE_P(op)) { @@ -744,7 +759,26 @@ try_again: case IS_DOUBLE: return zend_dval_to_lval(Z_DVAL_P(op)); case IS_STRING: - return ZEND_STRTOL(Z_STRVAL_P(op), NULL, 10); + { + zend_uchar type; + zend_long lval; + double dval; + if (0 == (type = is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &lval, &dval, silent ? 1 : -1))) { + if (!silent) { + zend_error(E_WARNING, "A non-numeric value encountered"); + } + return 0; + } else if (EXPECTED(type == IS_LONG)) { + return lval; + } else { + /* Previously we used strtol here, not is_numeric_string, + * and strtol gives you LONG_MAX/_MIN on overflow. + * We use use saturating conversion to emulate strtol()'s + * behaviour. + */ + return zend_dval_to_lval_cap(dval); + } + } case IS_ARRAY: return zend_hash_num_elements(Z_ARRVAL_P(op)) ? 1 : 0; case IS_OBJECT: @@ -766,6 +800,18 @@ try_again: } /* }}} */ +ZEND_API zend_long ZEND_FASTCALL _zval_get_long_func(zval *op) /* {{{ */ +{ + return _zval_get_long_func_ex(op, 1); +} +/* }}} */ + +static zend_long ZEND_FASTCALL _zval_get_long_func_noisy(zval *op) /* {{{ */ +{ + return _zval_get_long_func_ex(op, 0); +} +/* }}} */ + ZEND_API double ZEND_FASTCALL _zval_get_double_func(zval *op) /* {{{ */ { try_again: @@ -916,8 +962,8 @@ ZEND_API int ZEND_FASTCALL add_function(zval *result, zval *op1, zval *op2) /* { } else if (!converted) { ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_ADD, add_function); - zendi_convert_scalar_to_number(op1, op1_copy, result); - zendi_convert_scalar_to_number(op2, op2_copy, result); + zendi_convert_scalar_to_number(op1, op1_copy, result, 0); + zendi_convert_scalar_to_number(op2, op2_copy, result, 0); converted = 1; } else { zend_throw_error(NULL, "Unsupported operand types"); @@ -969,8 +1015,8 @@ ZEND_API int ZEND_FASTCALL sub_function(zval *result, zval *op1, zval *op2) /* { } else if (!converted) { ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB, sub_function); - zendi_convert_scalar_to_number(op1, op1_copy, result); - zendi_convert_scalar_to_number(op2, op2_copy, result); + zendi_convert_scalar_to_number(op1, op1_copy, result, 0); + zendi_convert_scalar_to_number(op2, op2_copy, result, 0); converted = 1; } else { zend_throw_error(NULL, "Unsupported operand types"); @@ -1016,8 +1062,8 @@ ZEND_API int ZEND_FASTCALL mul_function(zval *result, zval *op1, zval *op2) /* { } else if (!converted) { ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MUL, mul_function); - zendi_convert_scalar_to_number(op1, op1_copy, result); - zendi_convert_scalar_to_number(op2, op2_copy, result); + zendi_convert_scalar_to_number(op1, op1_copy, result, 0); + zendi_convert_scalar_to_number(op2, op2_copy, result, 0); converted = 1; } else { zend_throw_error(NULL, "Unsupported operand types"); @@ -1098,13 +1144,13 @@ ZEND_API int ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *op2) /* { ZVAL_LONG(result, 0); return SUCCESS; } else { - zendi_convert_scalar_to_number(op1, op1_copy, result); + zendi_convert_scalar_to_number(op1, op1_copy, result, 0); } if (Z_TYPE_P(op2) == IS_ARRAY) { ZVAL_LONG(result, 1L); return SUCCESS; } else { - zendi_convert_scalar_to_number(op2, op2_copy, result); + zendi_convert_scalar_to_number(op2, op2_copy, result, 0); } converted = 1; } else { @@ -1169,8 +1215,8 @@ ZEND_API int ZEND_FASTCALL div_function(zval *result, zval *op1, zval *op2) /* { } else if (!converted) { ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV, div_function); - zendi_convert_scalar_to_number(op1, op1_copy, result); - zendi_convert_scalar_to_number(op2, op2_copy, result); + zendi_convert_scalar_to_number(op1, op1_copy, result, 0); + zendi_convert_scalar_to_number(op2, op2_copy, result, 0); converted = 1; } else { zend_throw_error(NULL, "Unsupported operand types"); @@ -1377,13 +1423,13 @@ ZEND_API int ZEND_FASTCALL bitwise_or_function(zval *result, zval *op1, zval *op if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) { ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_OR, bitwise_or_function); - op1_lval = _zval_get_long_func(op1); + op1_lval = _zval_get_long_func_noisy(op1); } else { op1_lval = Z_LVAL_P(op1); } if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) { ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_OR); - op2_lval = _zval_get_long_func(op2); + op2_lval = _zval_get_long_func_noisy(op2); } else { op2_lval = Z_LVAL_P(op2); } @@ -1444,13 +1490,13 @@ ZEND_API int ZEND_FASTCALL bitwise_and_function(zval *result, zval *op1, zval *o if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) { ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_AND, bitwise_and_function); - op1_lval = _zval_get_long_func(op1); + op1_lval = _zval_get_long_func_noisy(op1); } else { op1_lval = Z_LVAL_P(op1); } if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) { ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_AND); - op2_lval = _zval_get_long_func(op2); + op2_lval = _zval_get_long_func_noisy(op2); } else { op2_lval = Z_LVAL_P(op2); } @@ -1511,13 +1557,13 @@ ZEND_API int ZEND_FASTCALL bitwise_xor_function(zval *result, zval *op1, zval *o if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) { ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_XOR, bitwise_xor_function); - op1_lval = _zval_get_long_func(op1); + op1_lval = _zval_get_long_func_noisy(op1); } else { op1_lval = Z_LVAL_P(op1); } if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) { ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_XOR); - op2_lval = _zval_get_long_func(op2); + op2_lval = _zval_get_long_func_noisy(op2); } else { op2_lval = Z_LVAL_P(op2); } @@ -1944,8 +1990,8 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2) ZVAL_LONG(result, zval_is_true(op1) ? 0 : -1); return SUCCESS; } else { - zendi_convert_scalar_to_number(op1, op1_copy, result); - zendi_convert_scalar_to_number(op2, op2_copy, result); + zendi_convert_scalar_to_number(op1, op1_copy, result, 1); + zendi_convert_scalar_to_number(op2, op2_copy, result, 1); converted = 1; } } else if (Z_TYPE_P(op1)==IS_ARRAY) { diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index f0ad0300fb..db6162a4e5 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -122,6 +122,16 @@ static zend_always_inline zend_long zend_dval_to_lval(double d) return (zend_long)d; } #endif + +static zend_always_inline zend_long zend_dval_to_lval_cap(double d) +{ + if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) { + return 0; + } else if (!ZEND_DOUBLE_FITS_LONG(d)) { + return (d > 0 ? ZEND_LONG_MAX : ZEND_LONG_MIN); + } + return (zend_long)d; +} /* }}} */ #define ZEND_IS_DIGIT(c) ((c) >= '0' && (c) <= '9') @@ -185,7 +195,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) { - register const unsigned char *e; + const unsigned char *e; if (n <= 0) { return NULL; } diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index f187129416..298dfb53fa 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -284,7 +284,7 @@ char *alloca(); # endif # elif defined(_MSC_VER) # define zend_always_inline __forceinline -# define zend_never_inline +# define zend_never_inline __declspec(noinline) # else # if __has_attribute(always_inline) # define zend_always_inline inline __attribute__((always_inline)) diff --git a/Zend/zend_smart_str.c b/Zend/zend_smart_str.c index bf29649972..c9b97acd1d 100644 --- a/Zend/zend_smart_str.c +++ b/Zend/zend_smart_str.c @@ -17,7 +17,7 @@ */ #include <zend.h> -#include "zend_smart_str_public.h" +#include "zend_smart_str.h" #define SMART_STR_OVERHEAD (ZEND_MM_OVERHEAD + _ZSTR_HEADER_SIZE) @@ -59,3 +59,61 @@ ZEND_API void ZEND_FASTCALL smart_str_realloc(smart_str *str, size_t len) str->s = (zend_string *) realloc(str->s, _ZSTR_HEADER_SIZE + str->a + 1); } } + +/* Windows uses VK_ESCAPE instead of \e */ +#ifndef VK_ESCAPE +#define VK_ESCAPE '\e' +#endif + +static size_t zend_compute_escaped_string_len(const char *s, size_t l) { + size_t i, len = l; + for (i = 0; i < l; ++i) { + char c = s[i]; + if (c == '\n' || c == '\r' || c == '\t' || + c == '\f' || c == '\v' || c == '\\' || c == VK_ESCAPE) { + len += 1; + } else if (c < 32 || c > 126) { + len += 3; + } + } + return len; +} + +ZEND_API void ZEND_FASTCALL smart_str_append_escaped(smart_str *str, const char *s, size_t l) { + char *res; + size_t i, len = zend_compute_escaped_string_len(s, l); + + smart_str_alloc(str, len, 0); + res = &ZSTR_VAL(str->s)[ZSTR_LEN(str->s)]; + ZSTR_LEN(str->s) += len; + + for (i = 0; i < l; ++i) { + unsigned char c = s[i]; + if (c < 32 || c == '\\' || c > 126) { + *res++ = '\\'; + switch (c) { + case '\n': *res++ = 'n'; break; + case '\r': *res++ = 'r'; break; + case '\t': *res++ = 't'; break; + case '\f': *res++ = 'f'; break; + case '\v': *res++ = 'v'; break; + case '\\': *res++ = '\\'; break; + case VK_ESCAPE: *res++ = 'e'; break; + default: + *res++ = 'x'; + if ((c >> 4) < 10) { + *res++ = (c >> 4) + '0'; + } else { + *res++ = (c >> 4) + 'A' - 10; + } + if ((c & 0xf) < 10) { + *res++ = (c & 0xf) + '0'; + } else { + *res++ = (c & 0xf) + 'A' - 10; + } + } + } else { + *res++ = c; + } + } +} diff --git a/Zend/zend_smart_str.h b/Zend/zend_smart_str.h index 7f8b55e9cf..f31d53e019 100644 --- a/Zend/zend_smart_str.h +++ b/Zend/zend_smart_str.h @@ -45,6 +45,7 @@ BEGIN_EXTERN_C() ZEND_API void ZEND_FASTCALL smart_str_erealloc(smart_str *str, size_t len); ZEND_API void ZEND_FASTCALL smart_str_realloc(smart_str *str, size_t len); +ZEND_API void ZEND_FASTCALL smart_str_append_escaped(smart_str *str, const char *s, size_t l); END_EXTERN_C() diff --git a/Zend/zend_sprintf.c b/Zend/zend_sprintf.c index 2620a8ed41..37d876d423 100644 --- a/Zend/zend_sprintf.c +++ b/Zend/zend_sprintf.c @@ -30,13 +30,14 @@ #if ZEND_BROKEN_SPRINTF int zend_sprintf(char *buffer, const char *format, ...) { + int len; va_list args; va_start(args, format); - vsprintf(buffer, format, args); + len = vsprintf(buffer, format, args); va_end(args); - return strlen(buffer); + return len; } #endif diff --git a/Zend/zend_string.h b/Zend/zend_string.h index 722fc3ae46..28aebb0ffc 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -323,7 +323,7 @@ static zend_always_inline zend_bool zend_string_equals(zend_string *s1, zend_str static zend_always_inline zend_ulong zend_inline_hash_func(const char *str, size_t len) { - register zend_ulong hash = Z_UL(5381); + zend_ulong hash = Z_UL(5381); /* variant with the hash unrolled eight times */ for (; len >= 8; len -= 8) { diff --git a/Zend/zend_type_info.h b/Zend/zend_type_info.h new file mode 100644 index 0000000000..bd3c3713d9 --- /dev/null +++ b/Zend/zend_type_info.h @@ -0,0 +1,68 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) 1998-2016 Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Dmitry Stogov <dmitry@zend.com> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef ZEND_TYPE_INFO_H +#define ZEND_TYPE_INFO_H + +#include "zend_types.h" + +#define MAY_BE_UNDEF (1 << IS_UNDEF) +#define MAY_BE_NULL (1 << IS_NULL) +#define MAY_BE_FALSE (1 << IS_FALSE) +#define MAY_BE_TRUE (1 << IS_TRUE) +#define MAY_BE_LONG (1 << IS_LONG) +#define MAY_BE_DOUBLE (1 << IS_DOUBLE) +#define MAY_BE_STRING (1 << IS_STRING) +#define MAY_BE_ARRAY (1 << IS_ARRAY) +#define MAY_BE_OBJECT (1 << IS_OBJECT) +#define MAY_BE_RESOURCE (1 << IS_RESOURCE) +#define MAY_BE_ANY (MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE) +#define MAY_BE_REF (1 << IS_REFERENCE) /* may be reference */ + +#define MAY_BE_ARRAY_SHIFT (IS_REFERENCE) + +#define MAY_BE_ARRAY_OF_NULL (MAY_BE_NULL << MAY_BE_ARRAY_SHIFT) +#define MAY_BE_ARRAY_OF_FALSE (MAY_BE_FALSE << MAY_BE_ARRAY_SHIFT) +#define MAY_BE_ARRAY_OF_TRUE (MAY_BE_TRUE << MAY_BE_ARRAY_SHIFT) +#define MAY_BE_ARRAY_OF_LONG (MAY_BE_LONG << MAY_BE_ARRAY_SHIFT) +#define MAY_BE_ARRAY_OF_DOUBLE (MAY_BE_DOUBLE << MAY_BE_ARRAY_SHIFT) +#define MAY_BE_ARRAY_OF_STRING (MAY_BE_STRING << MAY_BE_ARRAY_SHIFT) +#define MAY_BE_ARRAY_OF_ARRAY (MAY_BE_ARRAY << MAY_BE_ARRAY_SHIFT) +#define MAY_BE_ARRAY_OF_OBJECT (MAY_BE_OBJECT << MAY_BE_ARRAY_SHIFT) +#define MAY_BE_ARRAY_OF_RESOURCE (MAY_BE_RESOURCE << MAY_BE_ARRAY_SHIFT) +#define MAY_BE_ARRAY_OF_ANY (MAY_BE_ANY << MAY_BE_ARRAY_SHIFT) +#define MAY_BE_ARRAY_OF_REF (MAY_BE_REF << MAY_BE_ARRAY_SHIFT) + +#define MAY_BE_ARRAY_KEY_LONG (1<<21) +#define MAY_BE_ARRAY_KEY_STRING (1<<22) +#define MAY_BE_ARRAY_KEY_ANY (MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_KEY_STRING) + +#define MAY_BE_ERROR (1<<23) +#define MAY_BE_CLASS (1<<24) + +#endif /* ZEND_TYPE_INFO_H */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: t + * End: + */ diff --git a/Zend/zend_types.h b/Zend/zend_types.h index e141f8a544..5207386ccf 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -138,6 +138,7 @@ struct _zval_struct { uint32_t num_args; /* arguments number for EX(This) */ uint32_t fe_pos; /* foreach position */ uint32_t fe_iter_idx; /* foreach iterator index */ + uint32_t access_flags; /* class constant access flags */ } u2; }; @@ -274,7 +275,7 @@ typedef struct _HashTableIterator { struct _zend_object { zend_refcounted_h gc; - uint32_t handle; + uint32_t handle; // TODO: may be removed ??? zend_class_entry *ce; const zend_object_handlers *handlers; HashTable *properties; @@ -283,7 +284,7 @@ struct _zend_object { struct _zend_resource { zend_refcounted_h gc; - int handle; + int handle; // TODO: may be removed ??? int type; void *ptr; }; @@ -318,10 +319,12 @@ struct _zend_ast_ref { /* fake types */ #define _IS_BOOL 13 #define IS_CALLABLE 14 +#define IS_VOID 18 /* internal types */ #define IS_INDIRECT 15 #define IS_PTR 17 +#define _IS_ERROR 19 static zend_always_inline zend_uchar zval_get_type(const zval* pz) { return pz->u1.v.type; @@ -360,6 +363,9 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define Z_FE_ITER(zval) (zval).u2.fe_iter_idx #define Z_FE_ITER_P(zval_p) Z_FE_ITER(*(zval_p)) +#define Z_ACCESS_FLAGS(zval) (zval).u2.access_flags +#define Z_ACCESS_FLAGS_P(zval_p) Z_ACCESS_FLAGS(*(zval_p)) + #define Z_COUNTED(zval) (zval).value.counted #define Z_COUNTED_P(zval_p) Z_COUNTED(*(zval_p)) @@ -392,7 +398,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define IS_TYPE_REFCOUNTED (1<<2) #define IS_TYPE_COLLECTABLE (1<<3) #define IS_TYPE_COPYABLE (1<<4) -#define IS_TYPE_SYMBOLTABLE (1<<5) /* extended types */ #define IS_INTERNED_STRING_EX IS_STRING @@ -408,8 +413,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { /* zval.u1.v.const_flags */ #define IS_CONSTANT_UNQUALIFIED 0x010 -#define IS_LEXICAL_VAR 0x020 -#define IS_LEXICAL_REF 0x040 #define IS_CONSTANT_CLASS 0x080 /* __CLASS__ in trait */ #define IS_CONSTANT_IN_NAMESPACE 0x100 /* used only in opline->extended_value */ @@ -469,9 +472,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define Z_IMMUTABLE(zval) ((Z_TYPE_FLAGS(zval) & IS_TYPE_IMMUTABLE) != 0) #define Z_IMMUTABLE_P(zval_p) Z_IMMUTABLE(*(zval_p)) -#define Z_SYMBOLTABLE(zval) ((Z_TYPE_FLAGS(zval) & IS_TYPE_SYMBOLTABLE) != 0) -#define Z_SYMBOLTABLE_P(zval_p) Z_SYMBOLTABLE(*(zval_p)) - /* the following Z_OPT_* macros make better code when Z_TYPE_INFO accessed before */ #define Z_OPT_TYPE(zval) (Z_TYPE_INFO(zval) & Z_TYPE_MASK) #define Z_OPT_TYPE_P(zval_p) Z_OPT_TYPE(*(zval_p)) @@ -503,6 +503,9 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define Z_ISNULL(zval) (Z_TYPE(zval) == IS_NULL) #define Z_ISNULL_P(zval_p) Z_ISNULL(*(zval_p)) +#define Z_ISERROR(zval) (Z_TYPE(zval) == _IS_ERROR) +#define Z_ISERROR_P(zval_p) Z_ISERROR(*(zval_p)) + #define Z_LVAL(zval) (zval).value.lval #define Z_LVAL_P(zval_p) Z_LVAL(*(zval_p)) @@ -782,6 +785,10 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { Z_TYPE_INFO_P(z) = IS_PTR; \ } while (0) +#define ZVAL_ERROR(z) do { \ + Z_TYPE_INFO_P(z) = _IS_ERROR; \ + } while (0) + #define Z_REFCOUNT_P(pz) zval_refcount_p(pz) #define Z_SET_REFCOUNT_P(pz, rc) zval_set_refcount_p(pz, rc) #define Z_ADDREF_P(pz) zval_addref_p(pz) @@ -808,7 +815,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define Z_TRY_DELREF(z) Z_TRY_DELREF_P(&(z)) static zend_always_inline uint32_t zval_refcount_p(zval* pz) { - ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_IMMUTABLE_P(pz) || Z_SYMBOLTABLE_P(pz)); + ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_IMMUTABLE_P(pz)); return GC_REFCOUNT(Z_COUNTED_P(pz)); } diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index 98bad6878f..056cc72dae 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -267,59 +267,6 @@ ZEND_API void _zval_internal_ptr_dtor_wrapper(zval *zval_ptr) } #endif -ZEND_API int zval_copy_static_var(zval *p, int num_args, va_list args, zend_hash_key *key) /* {{{ */ -{ - zend_array *symbol_table; - HashTable *target = va_arg(args, HashTable*); - zend_bool is_ref; - zval tmp; - - if (Z_CONST_FLAGS_P(p) & (IS_LEXICAL_VAR|IS_LEXICAL_REF)) { - is_ref = Z_CONST_FLAGS_P(p) & IS_LEXICAL_REF; - - symbol_table = zend_rebuild_symbol_table(); - p = zend_hash_find(symbol_table, key->key); - if (!p) { - p = &tmp; - ZVAL_NULL(&tmp); - if (is_ref) { - ZVAL_NEW_REF(&tmp, &tmp); - zend_hash_add_new(symbol_table, key->key, &tmp); - Z_ADDREF_P(p); - } else { - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(key->key)); - } - } else { - if (Z_TYPE_P(p) == IS_INDIRECT) { - p = Z_INDIRECT_P(p); - if (Z_TYPE_P(p) == IS_UNDEF) { - if (!is_ref) { - zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(key->key)); - p = &tmp; - ZVAL_NULL(&tmp); - } else { - ZVAL_NULL(p); - } - } - } - if (is_ref) { - ZVAL_MAKE_REF(p); - Z_ADDREF_P(p); - } else if (Z_ISREF_P(p)) { - ZVAL_DUP(&tmp, Z_REFVAL_P(p)); - p = &tmp; - } else if (Z_REFCOUNTED_P(p)) { - Z_ADDREF_P(p); - } - } - } else if (Z_REFCOUNTED_P(p)) { - Z_ADDREF_P(p); - } - zend_hash_add(target, key->key, p); - return ZEND_HASH_APPLY_KEEP; -} -/* }}} */ - /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_variables.h b/Zend/zend_variables.h index bbcc4d175d..6958d6139f 100644 --- a/Zend/zend_variables.h +++ b/Zend/zend_variables.h @@ -106,8 +106,6 @@ static zend_always_inline void _zval_opt_copy_ctor_no_imm(zval *zvalue ZEND_FILE } } -ZEND_API int zval_copy_static_var(zval *p, int num_args, va_list args, zend_hash_key *key); - ZEND_API size_t zend_print_variable(zval *var); ZEND_API void _zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC); ZEND_API void _zval_internal_dtor_for_ptr(zval *zvalue ZEND_FILE_LINE_DC); diff --git a/Zend/zend_vm.h b/Zend/zend_vm.h index cae56c1c0b..39cbd8ee9c 100644 --- a/Zend/zend_vm.h +++ b/Zend/zend_vm.h @@ -25,6 +25,9 @@ BEGIN_EXTERN_C() ZEND_API void zend_vm_use_old_executor(void); ZEND_API void zend_vm_set_opcode_handler(zend_op* opcode); +ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* opcode, uint32_t op1_info, uint32_t op2_info, uint32_t res_info); +ZEND_API void zend_serialize_opcode_handler(zend_op *op); +ZEND_API void zend_deserialize_opcode_handler(zend_op *op); ZEND_API int zend_vm_call_opcode_handler(zend_execute_data *ex); END_EXTERN_C() diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 8e658f5d88..2557509381 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -685,7 +685,7 @@ ZEND_VM_HANDLER(13, ZEND_BOOL_NOT, CONST|TMPVAR|CV, ANY) 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 (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + if (OP1_TYPE == 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(); @@ -699,7 +699,7 @@ ZEND_VM_HANDLER(13, ZEND_BOOL_NOT, CONST|TMPVAR|CV, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, binary_op_type binary_op) +ZEND_VM_HELPER(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, binary_op_type binary_op) { USE_OPLINE zend_free_op free_op1, free_op2, free_op_data1; @@ -720,13 +720,6 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR| property = GET_OP2_ZVAL_PTR(BP_VAR_R); - if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - FREE_OP2(); - HANDLE_EXCEPTION(); - } - do { value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); @@ -744,7 +737,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR| /* 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, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -769,7 +762,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR| ZEND_VM_NEXT_OPCODE_EX(1, 2); } -ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, binary_op_type binary_op) +ZEND_VM_HELPER(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, binary_op_type binary_op) { USE_OPLINE zend_free_op free_op1, free_op2, free_op_data1; @@ -784,12 +777,6 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMPVAR| FREE_UNFETCHED_OP2(); HANDLE_EXCEPTION(); } - if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - FREE_UNFETCHED_OP2(); - HANDLE_EXCEPTION(); - } dim = GET_OP2_ZVAL_PTR(BP_VAR_R); @@ -807,22 +794,14 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMPVAR| zend_fetch_dimension_address_RW(&rv, container, dim, OP2_TYPE); value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - var_ptr = Z_INDIRECT(rv); - - if (UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - FREE_OP2(); - FREE_OP(free_op_data1); - FREE_OP1_VAR_PTR(); - HANDLE_EXCEPTION(); - } - if (UNEXPECTED(var_ptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR(rv))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { + ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); + var_ptr = Z_INDIRECT(rv); ZVAL_DEREF(var_ptr); SEPARATE_ZVAL_NOREF(var_ptr); @@ -840,7 +819,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMPVAR| ZEND_VM_NEXT_OPCODE_EX(1, 2); } -ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|CV, CONST|TMPVAR|CV, binary_op_type binary_op) +ZEND_VM_HELPER(zend_binary_assign_op_helper, VAR|CV, CONST|TMPVAR|CV, binary_op_type binary_op) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -851,13 +830,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|CV, CONST|TMPVAR|CV, binary_ value = GET_OP2_ZVAL_PTR(BP_VAR_R); var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW); - if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - FREE_OP2(); - HANDLE_EXCEPTION(); - } - - if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { + if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -877,247 +850,247 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|CV, CONST|TMPVAR|CV, binary_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(23, ZEND_ASSIGN_ADD, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(23, ZEND_ASSIGN_ADD, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE # if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED) if (EXPECTED(opline->extended_value == 0)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, add_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, add_function); } # endif if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, add_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, add_function); } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, add_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, add_function); } #else - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, add_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, add_function); #endif } -ZEND_VM_HANDLER(24, ZEND_ASSIGN_SUB, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(24, ZEND_ASSIGN_SUB, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE # if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED) if (EXPECTED(opline->extended_value == 0)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, sub_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, sub_function); } # endif if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, sub_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, sub_function); } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, sub_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, sub_function); } #else - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, sub_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, sub_function); #endif } -ZEND_VM_HANDLER(25, ZEND_ASSIGN_MUL, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(25, ZEND_ASSIGN_MUL, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE # if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED) if (EXPECTED(opline->extended_value == 0)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, mul_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, mul_function); } # endif if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, mul_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, mul_function); } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, mul_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, mul_function); } #else - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, mul_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, mul_function); #endif } -ZEND_VM_HANDLER(26, ZEND_ASSIGN_DIV, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(26, ZEND_ASSIGN_DIV, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE # if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED) if (EXPECTED(opline->extended_value == 0)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, div_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, div_function); } # endif if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, div_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, div_function); } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, div_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, div_function); } #else - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, div_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, div_function); #endif } -ZEND_VM_HANDLER(27, ZEND_ASSIGN_MOD, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(27, ZEND_ASSIGN_MOD, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE # if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED) if (EXPECTED(opline->extended_value == 0)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, mod_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, mod_function); } # endif if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, mod_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, mod_function); } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, mod_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, mod_function); } #else - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, mod_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, mod_function); #endif } -ZEND_VM_HANDLER(28, ZEND_ASSIGN_SL, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(28, ZEND_ASSIGN_SL, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE # if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED) if (EXPECTED(opline->extended_value == 0)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, shift_left_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, shift_left_function); } # endif if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, shift_left_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, shift_left_function); } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, shift_left_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, shift_left_function); } #else - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, shift_left_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, shift_left_function); #endif } -ZEND_VM_HANDLER(29, ZEND_ASSIGN_SR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(29, ZEND_ASSIGN_SR, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE # if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED) if (EXPECTED(opline->extended_value == 0)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, shift_right_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, shift_right_function); } # endif if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, shift_right_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, shift_right_function); } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, shift_right_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, shift_right_function); } #else - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, shift_right_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, shift_right_function); #endif } -ZEND_VM_HANDLER(30, ZEND_ASSIGN_CONCAT, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(30, ZEND_ASSIGN_CONCAT, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE # if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED) if (EXPECTED(opline->extended_value == 0)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, concat_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, concat_function); } # endif if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, concat_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, concat_function); } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, concat_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, concat_function); } #else - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, concat_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, concat_function); #endif } -ZEND_VM_HANDLER(31, ZEND_ASSIGN_BW_OR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(31, ZEND_ASSIGN_BW_OR, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE # if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED) if (EXPECTED(opline->extended_value == 0)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_or_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, bitwise_or_function); } # endif if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, bitwise_or_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_or_function); } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, bitwise_or_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, bitwise_or_function); } #else - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, bitwise_or_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_or_function); #endif } -ZEND_VM_HANDLER(32, ZEND_ASSIGN_BW_AND, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(32, ZEND_ASSIGN_BW_AND, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE # if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED) if (EXPECTED(opline->extended_value == 0)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_and_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, bitwise_and_function); } # endif if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, bitwise_and_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_and_function); } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, bitwise_and_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, bitwise_and_function); } #else - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, bitwise_and_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_and_function); #endif } -ZEND_VM_HANDLER(33, ZEND_ASSIGN_BW_XOR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(33, ZEND_ASSIGN_BW_XOR, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE # if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED) if (EXPECTED(opline->extended_value == 0)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_xor_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, bitwise_xor_function); } # endif if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, bitwise_xor_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_xor_function); } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, bitwise_xor_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, bitwise_xor_function); } #else - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, bitwise_xor_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_xor_function); #endif } -ZEND_VM_HANDLER(167, ZEND_ASSIGN_POW, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(167, ZEND_ASSIGN_POW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ) { #if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED) USE_OPLINE # if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED) if (EXPECTED(opline->extended_value == 0)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, pow_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, pow_function); } # endif if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, pow_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, pow_function); } else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, pow_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, pow_function); } #else - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, pow_function); + ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, pow_function); #endif } -ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, int inc) +ZEND_VM_HELPER(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, int inc) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -1136,12 +1109,6 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C property = GET_OP2_ZVAL_PTR(BP_VAR_R); - if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - FREE_OP2(); - HANDLE_EXCEPTION(); - } - do { if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -1157,7 +1124,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C /* 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, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -1192,17 +1159,17 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, inc, 1); + ZEND_VM_DISPATCH_TO_HELPER(zend_pre_incdec_property_helper, inc, 1); } -ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, inc, 0); + ZEND_VM_DISPATCH_TO_HELPER(zend_pre_incdec_property_helper, inc, 0); } -ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, int inc) +ZEND_VM_HELPER(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, int inc) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -1221,12 +1188,6 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR| property = GET_OP2_ZVAL_PTR(BP_VAR_R); - if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - FREE_OP2(); - HANDLE_EXCEPTION(); - } - do { if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -1241,7 +1202,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR| 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, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) { @@ -1272,17 +1233,17 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR| ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, inc, 1); + ZEND_VM_DISPATCH_TO_HELPER(zend_post_incdec_property_helper, inc, 1); } -ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, inc, 0); + ZEND_VM_DISPATCH_TO_HELPER(zend_post_incdec_property_helper, inc, 0); } -ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY) +ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY, SPEC(RETVAL)) { USE_OPLINE zend_free_op free_op1; @@ -1290,12 +1251,6 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY) var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); - if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - HANDLE_EXCEPTION(); - } - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { fast_long_increment_function(var_ptr); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -1304,7 +1259,7 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY) ZEND_VM_NEXT_OPCODE(); } - if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { + if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -1328,7 +1283,7 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY) +ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY, SPEC(RETVAL)) { USE_OPLINE zend_free_op free_op1; @@ -1336,12 +1291,6 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY) var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); - if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - HANDLE_EXCEPTION(); - } - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { fast_long_decrement_function(var_ptr); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -1350,7 +1299,7 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY) ZEND_VM_NEXT_OPCODE(); } - if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { + if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -1382,19 +1331,13 @@ ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY) var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); - if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - HANDLE_EXCEPTION(); - } - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); fast_long_increment_function(var_ptr); ZEND_VM_NEXT_OPCODE(); } - if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { + if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); ZEND_VM_NEXT_OPCODE(); } @@ -1421,19 +1364,13 @@ ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY) var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); - if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - HANDLE_EXCEPTION(); - } - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); fast_long_decrement_function(var_ptr); ZEND_VM_NEXT_OPCODE(); } - if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { + if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); ZEND_VM_NEXT_OPCODE(); } @@ -1482,7 +1419,7 @@ ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMPVAR|CV, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|VAR, int type) +ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type) { USE_OPLINE zend_free_op free_op1; @@ -1506,64 +1443,30 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|V name = zval_get_string(varname); } - if (OP2_TYPE != IS_UNUSED) { - zend_class_entry *ce; - - if (OP2_TYPE == IS_CONST) { - if (OP1_TYPE == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = 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)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - FREE_OP1(); - HANDLE_EXCEPTION(); - } - - ZEND_VM_C_GOTO(fetch_var_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)) { - if (OP1_TYPE != IS_CONST) { - zend_string_release(name); - } - FREE_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (OP1_TYPE == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - FREE_OP1(); - HANDLE_EXCEPTION(); - } - - ZEND_VM_C_GOTO(fetch_var_return); - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - if (OP1_TYPE != IS_CONST) { - zend_string_release(name); - } - FREE_OP1(); - HANDLE_EXCEPTION(); - } - if (OP1_TYPE == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + retval = zend_hash_find(target_symbol_table, name); + if (retval == NULL) { + 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() } - - FREE_OP1(); - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { + /* 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) { switch (type) { case BP_VAR_R: case BP_VAR_UNSET: @@ -1574,52 +1477,164 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|V 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; + /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + ZVAL_NULL(retval); 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) { - 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) { + FREE_OP1(); + } + + if (OP1_TYPE != IS_CONST) { + zend_string_release(name); + } + + ZEND_ASSERT(retval != NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { + ZVAL_UNREF(retval); + } + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } else { + ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_R); +} + +ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_W); +} + +ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_RW); +} + +ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ARG_NUM) +{ + USE_OPLINE + + if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_W); + } else { + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_R); + } +} + +ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_UNSET); +} + +ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMPVAR|CV, UNUSED, VAR_FETCH) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_IS); +} + +ZEND_VM_HELPER(zend_fetch_static_prop_helper, CONST|TMPVAR|CV, UNUSED|CONST|VAR, int type) +{ + USE_OPLINE + zend_free_op free_op1; + zval *varname; + zval *retval; + zend_string *name; + zend_class_entry *ce; + + SAVE_OPLINE(); + varname = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + + if (OP1_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); + } 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); + } + + if (OP2_TYPE == IS_CONST) { + if (OP1_TYPE == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = 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)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + FREE_OP1(); + HANDLE_EXCEPTION(); + } + + ZEND_VM_C_GOTO(fetch_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)) { + if (OP1_TYPE != IS_CONST) { + zend_string_release(name); } + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { - FREE_OP1(); - HANDLE_EXCEPTION(); + } 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) { + zend_string_release(name); } + FREE_OP1(); + HANDLE_EXCEPTION(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - FREE_OP1(); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (OP1_TYPE == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + FREE_OP1(); + HANDLE_EXCEPTION(); + } + + ZEND_VM_C_GOTO(fetch_static_prop_return); } } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + if (OP1_TYPE != IS_CONST) { + zend_string_release(name); + } + FREE_OP1(); + HANDLE_EXCEPTION(); + } + if (OP1_TYPE == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } + + FREE_OP1(); if (OP1_TYPE != IS_CONST) { zend_string_release(name); } -ZEND_VM_C_LABEL(fetch_var_return): +ZEND_VM_C_LABEL(fetch_static_prop_return): ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -1632,40 +1647,40 @@ ZEND_VM_C_LABEL(fetch_var_return): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(173, ZEND_FETCH_STATIC_PROP_R, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_R); + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_R); } -ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(174, ZEND_FETCH_STATIC_PROP_W, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_W); + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_W); } -ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(175, ZEND_FETCH_STATIC_PROP_RW, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_RW); + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_RW); } -ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, NUM) { USE_OPLINE if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_W); + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_W); } else { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_R); + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_R); } } -ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(178, ZEND_FETCH_STATIC_PROP_UNSET, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_UNSET); + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_UNSET); } -ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(176, ZEND_FETCH_STATIC_PROP_IS, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) { - ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_IS); + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_IS); } ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMPVAR|CV, CONST|TMPVAR|CV) @@ -1682,7 +1697,7 @@ ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -1691,20 +1706,16 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMPVAR|UNUSED|CV) SAVE_OPLINE(); container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); - if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP1_VAR_PTR(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -1713,14 +1724,10 @@ ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMPVAR|UNUSED|CV) SAVE_OPLINE(); container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW); - if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP1_VAR_PTR(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -1740,7 +1747,7 @@ ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, NUM) { USE_OPLINE zval *container; @@ -1749,21 +1756,16 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUS SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) { + if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); FREE_UNFETCHED_OP2(); FREE_UNFETCHED_OP1(); HANDLE_EXCEPTION(); } container = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); - if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP2(); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP2(); FREE_OP1_VAR_PTR(); @@ -1791,21 +1793,16 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMPVAR|CV) SAVE_OPLINE(); container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_UNSET); - if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP2(); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP1_VAR_PTR(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) { USE_OPLINE zend_free_op free_op1; @@ -1878,7 +1875,7 @@ ZEND_VM_C_LABEL(fetch_obj_r_no_object): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -1894,22 +1891,17 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMPVAR|CV) FREE_OP2(); HANDLE_EXCEPTION(); } - if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - FREE_OP2(); - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP1_VAR_PTR(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -1925,21 +1917,16 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMPVAR|CV) FREE_OP2(); HANDLE_EXCEPTION(); } - if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - FREE_OP2(); - HANDLE_EXCEPTION(); - } 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_RW); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP1_VAR_PTR(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) { USE_OPLINE zend_free_op free_op1; @@ -2012,7 +1999,7 @@ ZEND_VM_C_LABEL(fetch_obj_is_no_object): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, NUM) { USE_OPLINE zval *container; @@ -2031,21 +2018,16 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMPV FREE_OP2(); HANDLE_EXCEPTION(); } - if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) { + if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); FREE_OP2(); FREE_OP1_VAR_PTR(); HANDLE_EXCEPTION(); } - if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - FREE_OP2(); - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP1_VAR_PTR(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -2054,7 +2036,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMPV } } -ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -2071,44 +2053,89 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMPVAR|CV) property = GET_OP2_ZVAL_PTR(BP_VAR_R); - if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - FREE_OP2(); - HANDLE_EXCEPTION(); - } 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_UNSET); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP1_VAR_PTR(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST) +ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST|TMPVAR|CV) { USE_OPLINE zend_free_op free_op1; + zend_free_op free_op2; zval *container; + zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R); SAVE_OPLINE(); container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); ZEND_VM_C_LABEL(try_fetch_list): if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - zval *value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2))); + zval *value; + zend_string *str; + zend_ulong hval; - if (UNEXPECTED(value == NULL)) { - zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2))); - ZVAL_NULL(EX_VAR(opline->result.var)); +ZEND_VM_C_LABEL(assign_again_list): + if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +ZEND_VM_C_LABEL(num_index_list): + value = zend_hash_index_find(Z_ARRVAL_P(container), hval); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + + if (ZEND_HANDLE_NUMERIC(str, hval)) { + ZEND_VM_C_GOTO(num_index_list); + } + +ZEND_VM_C_LABEL(str_index_list): + value = zend_hash_find(Z_ARRVAL_P(container), str); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str)); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (UNEXPECTED(str != Z_STR_P(offset))) { + zend_string_release(str); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + ZEND_VM_C_GOTO(assign_again_list); + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + ZEND_VM_C_GOTO(str_index_list); + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + ZEND_VM_C_GOTO(num_index_list); + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + ZEND_VM_C_GOTO(num_index_list); + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + ZEND_VM_C_GOTO(num_index_list); + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset)); + hval = Z_RES_HANDLE_P(offset); } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); + zend_error(E_WARNING, "Illegal offset type"); } } else if (OP1_TYPE != IS_CONST && UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) && EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) { zval *result = EX_VAR(opline->result.var); - zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, EX_CONSTANT(opline->op2), BP_VAR_R, result); + zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result); if (retval) { if (result != retval) { @@ -2126,15 +2153,15 @@ ZEND_VM_C_LABEL(try_fetch_list): } ZVAL_NULL(EX_VAR(opline->result.var)); } + FREE_OP2(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, SPEC(OP_DATA=CONST|TMP|VAR|CV)) { USE_OPLINE - zend_free_op free_op1, free_op2; - zval *object; - zval *property_name; + zend_free_op free_op1, free_op2, free_op_data; + zval *object, *property_name, *value, tmp; SAVE_OPLINE(); object = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); @@ -2146,25 +2173,171 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV) } property_name = GET_OP2_ZVAL_PTR(BP_VAR_R); + value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R); - if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_OP2(); - HANDLE_EXCEPTION(); + if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + FREE_OP_DATA(); + ZEND_VM_C_GOTO(exit_assign_obj); + } + 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)); + } + FREE_OP_DATA(); + OBJ_RELEASE(obj); + ZEND_VM_C_GOTO(exit_assign_obj); + } + Z_DELREF_P(object); + } else { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + FREE_OP_DATA(); + ZEND_VM_C_GOTO(exit_assign_obj); + } + } while (0); + } + + if (OP2_TYPE == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +ZEND_VM_C_LABEL(fast_assign_obj): + value = zend_assign_to_variable(property, value, OP_DATA_TYPE); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + ZEND_VM_C_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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + ZEND_VM_C_GOTO(fast_assign_obj); + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (OP_DATA_TYPE == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (OP_DATA_TYPE != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (OP_DATA_TYPE == 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 (OP_DATA_TYPE == IS_CV && Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, Z_STR_P(property_name), value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + ZEND_VM_C_GOTO(exit_assign_obj); + } + } + } + + if (!Z_OBJ_HT_P(object)->write_property) { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + FREE_OP_DATA(); + ZEND_VM_C_GOTO(exit_assign_obj); + } + + /* separate our value if necessary */ + if (OP_DATA_TYPE == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (OP_DATA_TYPE != IS_TMP_VAR) { + ZVAL_DEREF(value); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, OP1_TYPE, property_name, OP2_TYPE, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (OP_DATA_TYPE == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + FREE_OP_DATA(); + } +ZEND_VM_C_LABEL(exit_assign_obj): FREE_OP2(); FREE_OP1_VAR_PTR(); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, SPEC(OP_DATA=CONST|TMP|VAR|CV)) { USE_OPLINE zend_free_op free_op1; zval *object_ptr; - zend_free_op free_op2, free_op_data1; + zend_free_op free_op2, free_op_data; zval *value; zval *variable_ptr; zval *dim; @@ -2172,13 +2345,6 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|CV) SAVE_OPLINE(); object_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); - if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - FREE_UNFETCHED_OP2(); - HANDLE_EXCEPTION(); - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { ZEND_VM_C_LABEL(try_assign_dim_array): if (OP2_TYPE == IS_UNUSED) { @@ -2186,7 +2352,7 @@ ZEND_VM_C_LABEL(try_assign_dim_array): 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"); - variable_ptr = &EG(error_zval); + variable_ptr = NULL; } } else { dim = GET_OP2_ZVAL_PTR(BP_VAR_R); @@ -2194,14 +2360,14 @@ ZEND_VM_C_LABEL(try_assign_dim_array): variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, OP2_TYPE, BP_VAR_W); FREE_OP2(); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - FREE_OP(free_op_data1); + if (UNEXPECTED(variable_ptr == NULL)) { + FREE_UNFETCHED_OP_DATA(); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type); + value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R); + value = zend_assign_to_variable(variable_ptr, value, OP_DATA_TYPE); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -2217,13 +2383,13 @@ ZEND_VM_C_LABEL(try_assign_dim_array): zend_free_op free_op2; zval *property_name = GET_OP2_ZVAL_PTR(BP_VAR_R); - zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, OP_DATA_TYPE, (opline+1)->op1, execute_data); FREE_OP2(); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { if (OP2_TYPE == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); + FREE_UNFETCHED_OP_DATA(); FREE_OP1_VAR_PTR(); HANDLE_EXCEPTION(); } else { @@ -2232,9 +2398,9 @@ ZEND_VM_C_LABEL(try_assign_dim_array): dim = GET_OP2_ZVAL_PTR(BP_VAR_R); offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); FREE_OP2(); - value = get_zval_ptr_r_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); + value = GET_OP_DATA_ZVAL_PTR_DEREF(BP_VAR_R); zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + FREE_OP_DATA(); } } else { zval_ptr_dtor_nogc(object_ptr); @@ -2244,17 +2410,14 @@ ZEND_VM_C_LABEL(assign_dim_convert_to_array): ZEND_VM_C_GOTO(try_assign_dim_array); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) { - ZEND_VM_C_GOTO(assign_dim_clean); - } ZEND_VM_C_GOTO(assign_dim_convert_to_array); + } else if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + ZEND_VM_C_GOTO(assign_dim_clean); } else { zend_error(E_WARNING, "Cannot use a scalar value as an array"); ZEND_VM_C_LABEL(assign_dim_clean): - dim = GET_OP2_ZVAL_PTR(BP_VAR_R); - FREE_OP2(); - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - FREE_OP(free_op_data1); + FREE_UNFETCHED_OP2(); + FREE_UNFETCHED_OP_DATA(); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -2265,7 +2428,7 @@ ZEND_VM_C_LABEL(assign_dim_clean): ZEND_VM_NEXT_OPCODE_EX(1, 2); } -ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV) +ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV, SPEC(RETVAL)) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -2276,7 +2439,7 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV) value = GET_OP2_ZVAL_PTR(BP_VAR_R); variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); - if (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { FREE_OP2(); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -2293,7 +2456,7 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV) +ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV, SRC) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -2302,54 +2465,50 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV) SAVE_OPLINE(); value_ptr = GET_OP2_ZVAL_PTR_PTR(BP_VAR_W); + variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); - if (OP2_TYPE == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets nor overloaded objects"); - FREE_UNFETCHED_OP1(); - HANDLE_EXCEPTION(); - } if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && - UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var)))) { + 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"); FREE_OP2_VAR_PTR(); HANDLE_EXCEPTION(); - } - if (OP2_TYPE == IS_VAR && - (value_ptr == &EG(uninitialized_zval) || - (opline->extended_value == ZEND_RETURNS_FUNCTION && - !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) { - if (!OP2_FREE && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op2.var)) != IS_INDIRECT)) { /* undo the effect of get_zval_ptr_ptr() */ - Z_TRY_ADDREF_P(value_ptr); - } + + } else if (OP2_TYPE == IS_VAR && + opline->extended_value == ZEND_RETURNS_FUNCTION && + UNEXPECTED(!(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { + zend_error(E_NOTICE, "Only variables should be assigned by reference"); if (UNEXPECTED(EG(exception) != NULL)) { FREE_OP2_VAR_PTR(); HANDLE_EXCEPTION(); } - ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ASSIGN); - } - variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); - if (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets nor overloaded objects"); - FREE_OP2_VAR_PTR(); - HANDLE_EXCEPTION(); - } - if ((OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || - (OP2_TYPE == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) { - variable_ptr = &EG(uninitialized_zval); + value_ptr = zend_assign_to_variable(variable_ptr, value_ptr, OP2_TYPE); + 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 { - 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 ((OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) || + (OP2_TYPE == 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); + } + + FREE_OP2_VAR_PTR(); } FREE_OP1_VAR_PTR(); - FREE_OP2_VAR_PTR(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -2375,13 +2534,10 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) object = Z_OBJ(old_execute_data->This); #if 0 if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) { - if (!(EX(opline)->op1.num & ZEND_CALL_CTOR_RESULT_UNUSED)) { #else if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { - if (!(call_info & ZEND_CALL_CTOR_RESULT_UNUSED)) { #endif - GC_REFCOUNT(object)--; - } + GC_REFCOUNT(object)--; if (GC_REFCOUNT(object) == 1) { zend_object_store_ctor_failed(object); } @@ -2452,7 +2608,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) } } -ZEND_VM_HANDLER(42, ZEND_JMP, ANY, ANY) +ZEND_VM_HANDLER(42, ZEND_JMP, JMP_ADDR, ANY) { USE_OPLINE @@ -2460,7 +2616,7 @@ ZEND_VM_HANDLER(42, ZEND_JMP, ANY, ANY) ZEND_VM_CONTINUE(); } -ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, ANY) +ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -2495,7 +2651,7 @@ ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, ANY) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, ANY) +ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -2529,7 +2685,7 @@ ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, ANY) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, ANY) +ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, JMP_ADDR, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -2566,7 +2722,7 @@ ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, ANY) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, ANY) +ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -2609,7 +2765,7 @@ ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, ANY) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, ANY) +ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -2649,7 +2805,7 @@ ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, ANY) ZEND_VM_JMP(opline); } -ZEND_VM_HANDLER(70, ZEND_FREE, TMPVAR, ANY) +ZEND_VM_HANDLER(70, ZEND_FREE, TMPVAR, LIVE_RANGE) { USE_OPLINE @@ -2658,7 +2814,7 @@ ZEND_VM_HANDLER(70, ZEND_FREE, TMPVAR, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(127, ZEND_FE_FREE, TMPVAR, ANY) +ZEND_VM_HANDLER(127, ZEND_FE_FREE, TMPVAR, LIVE_RANGE) { zval *var; USE_OPLINE @@ -2739,7 +2895,7 @@ ZEND_VM_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMPVAR|CV, NUM) { USE_OPLINE zend_free_op free_op2; @@ -2772,7 +2928,7 @@ ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMPVAR|CV, NUM) { USE_OPLINE zend_free_op free_op2; @@ -2805,7 +2961,7 @@ ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV, NUM) { USE_OPLINE zend_free_op free_op2; @@ -2858,7 +3014,7 @@ ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMPVAR|UNUSED|CV, CLASS_FETCH) { USE_OPLINE @@ -2901,7 +3057,7 @@ ZEND_VM_C_LABEL(try_class_name): } } -ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, NUM) { USE_OPLINE zval *function_name; @@ -3022,7 +3178,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, CONST|TMPVAR|UNUSED|CONSTRUCTOR|CV, NUM) { USE_OPLINE zval *function_name; @@ -3047,6 +3203,13 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); } + } else if (OP1_TYPE == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + FREE_UNFETCHED_OP2(); + HANDLE_EXCEPTION(); + } } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -3147,10 +3310,10 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE } } - if (OP1_TYPE != IS_CONST) { + if (OP1_TYPE == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -3163,7 +3326,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST) +ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM) { USE_OPLINE zend_function *fbc; @@ -3190,7 +3353,7 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(128, ZEND_INIT_DYNAMIC_CALL, ANY, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(128, ZEND_INIT_DYNAMIC_CALL, ANY, CONST|TMPVAR|CV, NUM) { USE_OPLINE zend_function *fbc; @@ -3403,7 +3566,7 @@ ZEND_VM_C_LABEL(try_function_name): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM) { USE_OPLINE zend_free_op free_op2; @@ -3462,7 +3625,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST) +ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM) { USE_OPLINE zval *func_name; @@ -3495,7 +3658,7 @@ ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(61, ZEND_INIT_FCALL, ANY, CONST) +ZEND_VM_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM) { USE_OPLINE zend_free_op free_op2; @@ -3525,12 +3688,13 @@ ZEND_VM_HANDLER(61, ZEND_INIT_FCALL, ANY, CONST) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY) +ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL)) { USE_OPLINE zend_execute_data *call = EX(call); zend_function *fbc = call->func; zval *ret; + zval retval; SAVE_OPLINE(); EX(call) = call->prev_execute_data; @@ -3538,7 +3702,7 @@ ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY) call->prev_execute_data = execute_data; EG(current_execute_data) = call; - ret = EX_VAR(opline->result.var); + ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); Z_VAR_FLAGS_P(ret) = 0; @@ -3548,7 +3712,7 @@ ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY) ZEND_ASSERT( EG(exception) || !call->func || !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var))); + zend_verify_internal_return_type(call->func, ret)); #endif EG(current_execute_data) = call->prev_execute_data; @@ -3556,7 +3720,7 @@ ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY) zend_vm_stack_free_call_frame(call); if (!RETURN_VALUE_USED(opline)) { - zval_ptr_dtor(EX_VAR(opline->result.var)); + zval_ptr_dtor(ret); } if (UNEXPECTED(EG(exception) != NULL)) { @@ -3571,7 +3735,7 @@ ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(130, ZEND_DO_UCALL, ANY, ANY) +ZEND_VM_HANDLER(130, ZEND_DO_UCALL, ANY, ANY, SPEC(RETVAL)) { USE_OPLINE zend_execute_data *call = EX(call); @@ -3596,7 +3760,7 @@ ZEND_VM_HANDLER(130, ZEND_DO_UCALL, ANY, ANY) ZEND_VM_ENTER(); } -ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY) +ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL)) { USE_OPLINE zend_execute_data *call = EX(call); @@ -3634,6 +3798,7 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY) } EG(scope) = EX(func)->op_array.scope; } else { + zval retval; ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) { @@ -3666,7 +3831,7 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY) } } - ret = EX_VAR(opline->result.var); + ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0; @@ -3676,7 +3841,7 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY) ZEND_ASSERT( EG(exception) || !call->func || !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var))); + zend_verify_internal_return_type(call->func, ret)); #endif EG(current_execute_data) = call->prev_execute_data; @@ -3684,7 +3849,7 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY) zend_vm_stack_free_call_frame(call); if (!RETURN_VALUE_USED(opline)) { - zval_ptr_dtor(EX_VAR(opline->result.var)); + zval_ptr_dtor(ret); } } @@ -3699,7 +3864,7 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY) +ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL)) { USE_OPLINE zend_execute_data *call = EX(call); @@ -3761,6 +3926,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY) } } else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) { int should_change_scope = 0; + zval retval; if (fbc->common.scope) { should_change_scope = 1; @@ -3792,7 +3958,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY) } } - ret = EX_VAR(opline->result.var); + ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0; @@ -3807,14 +3973,14 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY) ZEND_ASSERT( EG(exception) || !call->func || !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var))); + zend_verify_internal_return_type(call->func, ret)); #endif EG(current_execute_data) = call->prev_execute_data; zend_vm_stack_free_args(call); if (!RETURN_VALUE_USED(opline)) { - zval_ptr_dtor(EX_VAR(opline->result.var)); + zval_ptr_dtor(ret); } if (UNEXPECTED(should_change_scope)) { @@ -3823,6 +3989,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY) ZEND_VM_C_GOTO(fcall_end); } } else { /* ZEND_OVERLOADED_FUNCTION */ + zval retval; /* Not sure what should be done here if it's a static method */ object = Z_OBJ(call->This); if (UNEXPECTED(object == NULL)) { @@ -3839,11 +4006,12 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY) EG(scope) = fbc->common.scope; - ZVAL_NULL(EX_VAR(opline->result.var)); + ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; + ZVAL_NULL(ret); call->prev_execute_data = execute_data; EG(current_execute_data) = call; - object->handlers->call_method(fbc->common.function_name, object, call, EX_VAR(opline->result.var)); + object->handlers->call_method(fbc->common.function_name, object, call, ret); EG(current_execute_data) = call->prev_execute_data; zend_vm_stack_free_args(call); @@ -3854,9 +4022,9 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY) efree(fbc); if (!RETURN_VALUE_USED(opline)) { - zval_ptr_dtor(EX_VAR(opline->result.var)); + zval_ptr_dtor(ret); } else { - Z_VAR_FLAGS_P(EX_VAR(opline->result.var)) = 0; + Z_VAR_FLAGS_P(ret) = 0; } } @@ -3865,13 +4033,10 @@ ZEND_VM_C_LABEL(fcall_end_change_scope): object = Z_OBJ(call->This); #if 0 if (UNEXPECTED(EG(exception) != NULL) && (opline->op1.num & ZEND_CALL_CTOR)) { - if (!(opline->op1.num & ZEND_CALL_CTOR_RESULT_UNUSED)) { #else if (UNEXPECTED(EG(exception) != NULL) && (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR)) { - if (!(ZEND_CALL_INFO(call) & ZEND_CALL_CTOR_RESULT_UNUSED)) { #endif - GC_REFCOUNT(object)--; - } + GC_REFCOUNT(object)--; if (GC_REFCOUNT(object) == 1) { zend_object_store_ctor_failed(object); } @@ -3942,8 +4107,6 @@ ZEND_VM_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV, UNUSED) if (UNEXPECTED(EG(exception) != NULL)) { if (OP1_TYPE == IS_CONST) { zval_ptr_dtor_nogc(retval_ptr); - } else { - FREE_OP1(); } } #endif @@ -3965,14 +4128,14 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY) ZVAL_NULL(EX(return_value)); } } else if (!EX(return_value)) { - if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_TMP_VAR ) { + if (OP1_TYPE & (IS_VAR|IS_TMP_VAR)) { if (Z_REFCOUNTED_P(free_op1) && !Z_DELREF_P(free_op1)) { SAVE_OPLINE(); zval_dtor_func_for_ptr(Z_COUNTED_P(free_op1)); } } } else { - if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) { + if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); if (OP1_TYPE == IS_CONST) { if (UNEXPECTED(Z_OPT_COPYABLE_P(EX(return_value)))) { @@ -4001,7 +4164,7 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY) ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); } -ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY) +ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC) { USE_OPLINE zval *retval_ptr; @@ -4010,7 +4173,7 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY) SAVE_OPLINE(); do { - if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR || + if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR)) || (OP1_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { /* Not supposed to happen, but we'll allow it */ zend_error(E_NOTICE, "Only variable references should be returned by reference"); @@ -4032,11 +4195,6 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY) retval_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); - if (OP1_TYPE == IS_VAR && UNEXPECTED(retval_ptr == NULL)) { - zend_throw_error(NULL, "Cannot return string offsets by reference"); - HANDLE_EXCEPTION(); - } - if (OP1_TYPE == IS_VAR) { if (retval_ptr == &EG(uninitialized_zval) || (opline->extended_value == ZEND_RETURNS_FUNCTION && @@ -4075,7 +4233,7 @@ ZEND_VM_HANDLER(161, ZEND_GENERATOR_RETURN, CONST|TMP|VAR|CV, ANY) retval = GET_OP1_ZVAL_PTR(BP_VAR_R); /* Copy return value into generator->retval */ - if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) { + if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) { ZVAL_COPY_VALUE(&generator->retval, retval); if (OP1_TYPE == IS_CONST) { if (UNEXPECTED(Z_OPT_COPYABLE(generator->retval))) { @@ -4148,7 +4306,7 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY) HANDLE_EXCEPTION(); } -ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV) +ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, JMP_ADDR) { USE_OPLINE zend_class_entry *ce, *catch_ce; @@ -4158,8 +4316,8 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV) /* Check whether an exception has been thrown, if not, jump over code */ zend_exception_restore(); if (EG(exception) == NULL) { - ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->extended_value]); - ZEND_VM_CONTINUE(); /* CHECK_ME */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); if (UNEXPECTED(catch_ce == NULL)) { @@ -4181,8 +4339,8 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV) zend_throw_exception_internal(NULL); HANDLE_EXCEPTION(); } - ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->extended_value]); - ZEND_VM_CONTINUE(); /* CHECK_ME */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } } @@ -4198,7 +4356,7 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV) } } -ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY) +ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, NUM) { USE_OPLINE zval *value, *arg; @@ -4215,7 +4373,7 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(116, ZEND_SEND_VAL_EX, CONST|TMP, ANY) +ZEND_VM_HANDLER(116, ZEND_SEND_VAL_EX, CONST|TMP, NUM, SPEC(QUICK_ARG)) { USE_OPLINE zval *value, *arg; @@ -4246,7 +4404,7 @@ ZEND_VM_C_LABEL(send_val_by_ref): ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, ANY) +ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, NUM) { USE_OPLINE zval *varptr, *arg; @@ -4285,7 +4443,7 @@ ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR, ANY) +ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR, NUM, SEND) { USE_OPLINE zend_free_op free_op1; @@ -4322,7 +4480,7 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY) +ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, NUM) { USE_OPLINE zend_free_op free_op1; @@ -4331,15 +4489,8 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY) SAVE_OPLINE(); varptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); - if (OP1_TYPE == IS_VAR && UNEXPECTED(varptr == NULL)) { - zend_throw_error(NULL, "Only variables can be passed by reference"); - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - ZVAL_UNDEF(arg); - HANDLE_EXCEPTION(); - } - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - if (OP1_TYPE == IS_VAR && UNEXPECTED(varptr == &EG(error_zval))) { + if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISERROR_P(varptr))) { ZVAL_NEW_REF(arg, &EG(uninitialized_zval)); ZEND_VM_NEXT_OPCODE(); } @@ -4357,7 +4508,7 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(66, ZEND_SEND_VAR_EX, VAR|CV, ANY) +ZEND_VM_HANDLER(66, ZEND_SEND_VAR_EX, VAR|CV, NUM, SPEC(QUICK_ARG)) { USE_OPLINE zval *varptr, *arg; @@ -4668,7 +4819,7 @@ ZEND_VM_C_LABEL(send_array): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(120, ZEND_SEND_USER, VAR|CV, ANY) +ZEND_VM_HANDLER(120, ZEND_SEND_USER, VAR|CV, NUM) { USE_OPLINE zval *arg, *param; @@ -4723,7 +4874,7 @@ ZEND_VM_HANDLER(120, ZEND_SEND_USER, VAR|CV, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY) +ZEND_VM_HANDLER(63, ZEND_RECV, NUM, ANY) { USE_OPLINE uint32_t arg_num = opline->op1.num; @@ -4744,7 +4895,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST) +ZEND_VM_HANDLER(64, ZEND_RECV_INIT, NUM, CONST) { USE_OPLINE uint32_t arg_num; @@ -4783,7 +4934,7 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY) +ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, ANY) { USE_OPLINE uint32_t arg_num = opline->op1.num; @@ -4834,7 +4985,7 @@ ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMPVAR|CV, ANY) 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 (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + if (OP1_TYPE == 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(); @@ -4922,12 +5073,13 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(68, ZEND_NEW, CONST|VAR, ANY) +ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, ANY, NUM) { USE_OPLINE - zval object_zval; + zval *result; zend_function *constructor; zend_class_entry *ce; + zend_execute_data *call; SAVE_OPLINE(); if (OP1_TYPE == IS_CONST) { @@ -4939,42 +5091,50 @@ ZEND_VM_HANDLER(68, ZEND_NEW, CONST|VAR, ANY) } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); } + } else if (OP1_TYPE == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + HANDLE_EXCEPTION(); + } } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (UNEXPECTED(object_init_ex(&object_zval, ce) != SUCCESS)) { + + result = EX_VAR(opline->result.var); + if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { HANDLE_EXCEPTION(); } - constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval)); + constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); if (constructor == NULL) { - if (EXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval); - } else { - OBJ_RELEASE(Z_OBJ(object_zval)); + /* 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); } - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + + /* 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 { /* We are not handling overloaded classes right now */ - zend_execute_data *call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR | - (EXPECTED(RETURN_VALUE_USED(opline)) ? 0 : ZEND_CALL_CTOR_RESULT_UNUSED), + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR, constructor, opline->extended_value, ce, - Z_OBJ(object_zval)); - call->prev_execute_data = EX(call); - EX(call) = call; - - if (EXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), &object_zval); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + Z_OBJ_P(result)); + Z_ADDREF_P(result); } + + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|CV, ANY) +ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY) { USE_OPLINE zend_free_op free_op1; @@ -5013,19 +5173,15 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|CV, ANY) } while (0); ce = Z_OBJCE_P(obj); - clone = ce ? ce->clone : NULL; - clone_call = Z_OBJ_HT_P(obj)->clone_obj; + clone = ce->clone; + clone_call = Z_OBJ_HT_P(obj)->clone_obj; if (UNEXPECTED(clone_call == NULL)) { - if (ce) { - zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); - } else { - zend_throw_error(NULL, "Trying to clone an uncloneable object"); - } + zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); FREE_OP1(); HANDLE_EXCEPTION(); } - if (ce && clone) { + 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. */ @@ -5045,124 +5201,142 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|CV, ANY) } } - if (EXPECTED(EG(exception) == NULL)) { - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); - if (UNEXPECTED(!RETURN_VALUE_USED(opline)) || UNEXPECTED(EG(exception) != NULL)) { - OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); - } + ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); + if (UNEXPECTED(EG(exception) != NULL)) { + OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); } + FREE_OP1(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST) +ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED, CONST, CONST_FETCH) { USE_OPLINE + zend_constant *c; SAVE_OPLINE(); - if (OP1_TYPE == IS_UNUSED) { - 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 ((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_NOTICE, "Use of undefined constant %s - assumed '%s'", - Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var))); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + 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 ((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 { - zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); + 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_NOTICE, "Use of undefined constant %s - assumed '%s'", + Z_STRVAL_P(EX_VAR(opline->result.var)), Z_STRVAL_P(EX_VAR(opline->result.var))); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c); + zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + 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 + 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 - } else { - /* class constant */ - zend_class_entry *ce; - zval *value; - 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))); - ZVAL_DEREF(value); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CONST) +{ + zend_class_entry *ce; + zend_class_constant *c; + zval *value; + 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))); + 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)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); - } - HANDLE_EXCEPTION(); + 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)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + } + } else { + if (OP1_TYPE == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZEND_ASSERT(EG(exception)); + HANDLE_EXCEPTION(); } } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); - if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { - ZVAL_DEREF(value); - break; - } } + if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { + break; + } + } - if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { - ZVAL_DEREF(value); - if (Z_CONSTANT_P(value)) { - EG(scope) = ce; - zval_update_constant_ex(value, 1, NULL); - EG(scope) = EX(func)->op_array.scope; - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - if (OP1_TYPE == 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); + if (EXPECTED((c = zend_hash_find_ptr(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { + if (!zend_verify_const_access(c, EG(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))); + HANDLE_EXCEPTION(); + } + value = &c->value; + if (Z_CONSTANT_P(value)) { + EG(scope) = ce; + zval_update_constant_ex(value, 1, NULL); + EG(scope) = EX(func)->op_array.scope; + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } + } + if (OP1_TYPE == IS_CONST) { + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); } else { - zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); } - } 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); + zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + HANDLE_EXCEPTION(); } -#else + } 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); -#endif } +#else + ZVAL_COPY(EX_VAR(opline->result.var), value); +#endif + ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, REF) { USE_OPLINE zend_free_op free_op1; @@ -5172,11 +5346,6 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSE if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); - if (OP1_TYPE == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); FREE_OP1_VAR_PTR(); @@ -5261,7 +5430,7 @@ ZEND_VM_C_LABEL(num_index): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV) +ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|NEXT|CV, ARRAY_INIT|REF) { zval *array; uint32_t size; @@ -5292,7 +5461,7 @@ ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|UNUSE } } -ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY) +ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE) { USE_OPLINE zend_free_op free_op1; @@ -5394,7 +5563,7 @@ ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY) +ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY, EVAL) { USE_OPLINE zend_op_array *new_op_array=NULL; @@ -5523,7 +5692,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ISSET) { USE_OPLINE zval tmp, *varname; @@ -5532,7 +5701,6 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) SAVE_OPLINE(); if (OP1_TYPE == IS_CV && - OP2_TYPE == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { zval *var = EX_VAR(opline->op1.var); @@ -5569,33 +5737,66 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) varname = &tmp; } - if (OP2_TYPE != IS_UNUSED) { - zend_class_entry *ce; + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); - if (OP2_TYPE == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +ZEND_VM_HANDLER(179, ZEND_UNSET_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) +{ + USE_OPLINE + zval tmp, *varname; + zend_class_entry *ce; + zend_free_op free_op1; + + SAVE_OPLINE(); + + 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_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 (OP2_TYPE == 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)) { - 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)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - FREE_OP1(); - HANDLE_EXCEPTION(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + FREE_OP1(); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(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)); + } + FREE_OP1(); + HANDLE_EXCEPTION(); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + zend_std_unset_static_property(ce, Z_STR_P(varname)); if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -5604,7 +5805,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -5620,11 +5821,6 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMPVAR|CV) FREE_UNFETCHED_OP2(); HANDLE_EXCEPTION(); } - if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - FREE_UNFETCHED_OP2(); - HANDLE_EXCEPTION(); - } offset = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); do { @@ -5703,7 +5899,7 @@ ZEND_VM_C_LABEL(num_index_dim): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -5717,11 +5913,6 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV) FREE_UNFETCHED_OP2(); HANDLE_EXCEPTION(); } - if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - FREE_UNFETCHED_OP2(); - HANDLE_EXCEPTION(); - } offset = GET_OP2_ZVAL_PTR(BP_VAR_R); do { @@ -5747,7 +5938,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, ANY) +ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -5852,7 +6043,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, ANY) } } -ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, ANY) +ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -6017,7 +6208,7 @@ ZEND_VM_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, ANY) } } -ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY) +ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, JMP_ADDR) { USE_OPLINE zval *array; @@ -6056,7 +6247,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY) break; } Z_FE_POS_P(array) = pos + 1; - if (opline->result_type == IS_TMP_VAR) { + if (opline->result_type & (IS_TMP_VAR|IS_CV)) { if (!p->key) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); } else { @@ -6100,7 +6291,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY) pos++; p++; } - if (opline->result_type == IS_TMP_VAR) { + if (opline->result_type & (IS_TMP_VAR|IS_CV)) { if (UNEXPECTED(!p->key)) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); } else if (ZSTR_VAL(p->key)[0]) { @@ -6135,13 +6326,11 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY) * In case that ever happens we need an additional flag. */ iter->funcs->move_forward(iter); if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } if (UNEXPECTED(iter->funcs->valid(iter) == FAILURE)) { /* reached end of iteration */ if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } ZEND_VM_C_GOTO(fe_fetch_r_exit); @@ -6149,18 +6338,16 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY) } value = iter->funcs->get_current_data(iter); if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } if (!value) { /* failure in get_current_data */ ZEND_VM_C_GOTO(fe_fetch_r_exit); } - if (opline->result_type == IS_TMP_VAR) { + if (opline->result_type & (IS_TMP_VAR|IS_CV)) { if (iter->funcs->get_current_key) { iter->funcs->get_current_key(iter, EX_VAR(opline->result.var)); if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } } else { @@ -6194,7 +6381,7 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit): ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY) +ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_ADDR) { USE_OPLINE zval *array; @@ -6234,7 +6421,7 @@ ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY) } break; } - if (opline->result_type == IS_TMP_VAR) { + if (opline->result_type & (IS_TMP_VAR|IS_CV)) { if (!p->key) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); } else { @@ -6292,7 +6479,7 @@ ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY) pos++; p++; } - if (opline->result_type == IS_TMP_VAR) { + if (opline->result_type & (IS_TMP_VAR|IS_CV)) { if (UNEXPECTED(!p->key)) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); } else if (ZSTR_VAL(p->key)[0]) { @@ -6327,13 +6514,11 @@ ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY) * In case that ever happens we need an additional flag. */ iter->funcs->move_forward(iter); if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } if (UNEXPECTED(iter->funcs->valid(iter) == FAILURE)) { /* reached end of iteration */ if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } ZEND_VM_C_GOTO(fe_fetch_w_exit); @@ -6341,18 +6526,16 @@ ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY) } value = iter->funcs->get_current_data(iter); if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } if (!value) { /* failure in get_current_data */ ZEND_VM_C_GOTO(fe_fetch_w_exit); } - if (opline->result_type == IS_TMP_VAR) { + if (opline->result_type & (IS_TMP_VAR|IS_CV)) { if (iter->funcs->get_current_key) { iter->funcs->get_current_key(iter, EX_VAR(opline->result.var)); if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } } else { @@ -6395,14 +6578,13 @@ ZEND_VM_C_LABEL(fe_fetch_w_exit): ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) +ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ISSET) { USE_OPLINE zval *value; int result; if (OP1_TYPE == IS_CV && - OP2_TYPE == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { value = EX_VAR(opline->op1.var); if (opline->extended_value & ZEND_ISSET) { @@ -6423,6 +6605,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) } else { zend_free_op free_op1; zval tmp, *varname; + HashTable *target_symbol_table; SAVE_OPLINE(); varname = GET_OP1_ZVAL_PTR(BP_VAR_IS); @@ -6432,56 +6615,14 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) varname = &tmp; } - if (OP2_TYPE != IS_UNUSED) { - zend_class_entry *ce; - - 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*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - ZEND_VM_C_GOTO(is_var_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_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (OP1_TYPE == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - ZEND_VM_C_GOTO(is_var_return); - } - } - - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if (OP1_TYPE == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); - } - } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); - } + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); } FREE_OP1(); -ZEND_VM_C_LABEL(is_var_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); @@ -6495,7 +6636,91 @@ ZEND_VM_C_LABEL(is_var_return): } } -ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, ISSET) +{ + USE_OPLINE + zval *value; + int result; + zend_free_op free_op1; + zval tmp, *varname; + 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 (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*)); + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + 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); + if (UNEXPECTED(ce == NULL)) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(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)); + } + FREE_OP1(); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (OP1_TYPE == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } + + ZEND_VM_C_GOTO(is_static_prop_return); + } + } + + value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + + if (OP1_TYPE == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + } + + if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + FREE_OP1(); + +ZEND_VM_C_LABEL(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(); +} + +ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, ISSET) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -6598,6 +6823,9 @@ ZEND_VM_C_LABEL(num_index_prop): if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { lval = Z_LVAL_P(offset); ZEND_VM_C_LABEL(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; @@ -6632,7 +6860,7 @@ ZEND_VM_C_LABEL(isset_dim_obj_exit): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, ISSET) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -6751,7 +6979,7 @@ ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, ANY) +ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -6790,7 +7018,7 @@ ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, ANY) +ZEND_VM_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR) { USE_OPLINE zend_free_op free_op1; @@ -6909,41 +7137,42 @@ ZEND_VM_HANDLER(139, ZEND_DECLARE_CLASS, ANY, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(140, ZEND_DECLARE_INHERITED_CLASS, ANY, ANY) +ZEND_VM_HANDLER(140, ZEND_DECLARE_INHERITED_CLASS, ANY, VAR) { USE_OPLINE SAVE_OPLINE(); - Z_CE_P(EX_VAR(opline->result.var)) = do_bind_inherited_class(&EX(func)->op_array, opline, EG(class_table), Z_CE_P(EX_VAR(opline->extended_value)), 0); + Z_CE_P(EX_VAR(opline->result.var)) = do_bind_inherited_class(&EX(func)->op_array, opline, EG(class_table), Z_CE_P(EX_VAR(opline->op2.var)), 0); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(145, ZEND_DECLARE_INHERITED_CLASS_DELAYED, ANY, ANY) +ZEND_VM_HANDLER(145, ZEND_DECLARE_INHERITED_CLASS_DELAYED, ANY, VAR) { USE_OPLINE zval *zce, *orig_zce; SAVE_OPLINE(); - if ((zce = zend_hash_find(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op2)))) == NULL || - ((orig_zce = zend_hash_find(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1)))) != NULL && + 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 && 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->extended_value)), 0); + do_bind_inherited_class(&EX(func)->op_array, opline, EG(class_table), Z_CE_P(EX_VAR(opline->op2.var)), 0); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, ANY, ANY) +ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, ANY, ANY, JMP_ADDR) { zend_class_entry *ce; USE_OPLINE SAVE_OPLINE(); - ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op2))); + ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1))); Z_CE_P(EX_VAR(opline->result.var)) = ce; ZEND_ASSERT(ce != NULL); if (ce->ce_flags & ZEND_ACC_ANON_BOUND) { - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op1)); + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLEMENT_INTERFACES|ZEND_ACC_IMPLEMENT_TRAITS))) { @@ -6953,21 +7182,22 @@ ZEND_VM_HANDLER(171, ZEND_DECLARE_ANON_CLASS, ANY, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(172, ZEND_DECLARE_ANON_INHERITED_CLASS, ANY, ANY) +ZEND_VM_HANDLER(172, ZEND_DECLARE_ANON_INHERITED_CLASS, ANY, VAR, JMP_ADDR) { zend_class_entry *ce; USE_OPLINE SAVE_OPLINE(); - ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op2))); + ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1))); Z_CE_P(EX_VAR(opline->result.var)) = ce; ZEND_ASSERT(ce != NULL); if (ce->ce_flags & ZEND_ACC_ANON_BOUND) { - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op1)); + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } - zend_do_inheritance(ce, Z_CE_P(EX_VAR(opline->extended_value))); + zend_do_inheritance(ce, Z_CE_P(EX_VAR(opline->op2.var))); ce->ce_flags |= ZEND_ACC_ANON_BOUND; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -6981,7 +7211,7 @@ ZEND_VM_HANDLER(141, ZEND_DECLARE_FUNCTION, ANY, ANY) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY) +ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY, NUM) { USE_OPLINE @@ -6996,7 +7226,7 @@ ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMPVAR|CV, CONST|VAR) +ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) { USE_OPLINE zend_free_op free_op1; @@ -7021,6 +7251,13 @@ ZEND_VM_C_LABEL(try_instanceof): } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(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)); + FREE_OP1(); + HANDLE_EXCEPTION(); + } } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } @@ -7131,7 +7368,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) * are logically thrown at the end of the foreach loop, so adjust the * op_num. */ - op_num = EX(func)->op_array.brk_cont_array[exc_opline->op2.num].brk; + op_num = EX(func)->op_array.live_range[exc_opline->op2.num].end; } } @@ -7309,7 +7546,7 @@ ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSED) +ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSED, SRC) { USE_OPLINE @@ -7336,7 +7573,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE 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 (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) { + if (OP1_TYPE & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -7351,12 +7588,6 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE } else { zval *value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); - if (OP1_TYPE == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - FREE_UNFETCHED_OP2(); - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (OP1_TYPE == IS_VAR && @@ -7560,7 +7791,7 @@ ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY) +ZEND_VM_HANDLER(162, ZEND_FAST_CALL, JMP_ADDR, TRY_CATCH, FAST_CALL) { USE_OPLINE zval *fast_call = EX_VAR(opline->result.var); @@ -7576,7 +7807,7 @@ ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY) ZEND_VM_CONTINUE(); } -ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, ANY) +ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, TRY_CATCH, FAST_RET) { USE_OPLINE zval *fast_call = EX_VAR(opline->op1.var); @@ -7585,7 +7816,7 @@ ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, ANY) const zend_op *fast_ret = EX(func)->op_array.opcodes + fast_call->u2.lineno; ZEND_VM_SET_OPCODE(fast_ret + 1); if (fast_ret->extended_value & ZEND_FAST_CALL_FROM_FINALLY) { - fast_call->u2.lineno = fast_ret->op2.opline_num; + fast_call->u2.lineno = EX(func)->op_array.try_catch_array[fast_ret->op2.num].finally_op - 2; } ZEND_VM_CONTINUE(); } else { @@ -7593,15 +7824,19 @@ ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, ANY) USE_OPLINE if (opline->extended_value == ZEND_FAST_RET_TO_FINALLY) { - cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, opline->op2.opline_num); - ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]); + uint32_t finally_op = EX(func)->op_array.try_catch_array[opline->op2.num].finally_op; + + cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, finally_op); + ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[finally_op]); ZEND_VM_CONTINUE(); } else { EG(exception) = Z_OBJ_P(fast_call); Z_OBJ_P(fast_call) = NULL; if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) { - cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, opline->op2.opline_num); - ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]); + uint32_t catch_op = EX(func)->op_array.try_catch_array[opline->op2.num].catch_op; + + cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, catch_op); + ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op]); ZEND_VM_CONTINUE(); } else { cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, 0); @@ -7751,7 +7986,7 @@ ZEND_VM_C_LABEL(try_strlen): ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMP|VAR|CV, ANY) +ZEND_VM_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMP|VAR|CV, ANY, TYPE) { USE_OPLINE zval *value; @@ -7764,7 +7999,7 @@ ZEND_VM_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMP|VAR|CV, ANY) if (OP1_TYPE != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { zend_class_entry *ce = Z_OBJCE_P(value); - if (UNEXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) || + if (EXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) || EXPECTED(memcmp(ZSTR_VAL(ce->name), "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) { result = 1; } @@ -7797,7 +8032,6 @@ ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY) result = 1; } else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op1), 0)) == NULL) { result = 0; - ZVAL_FALSE(EX_VAR(opline->result.var)); } else { CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), c); result = 1; @@ -7807,16 +8041,14 @@ ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, ANY) +ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, JMP_ADDR) { USE_OPLINE if (EG(assertions) <= 0) { zend_op *target = OP_JMP_ADDR(opline, opline->op2); - zend_op *result = target - 1; - SKIP_EXT_OPLINE(result); - if (RETURN_VALUE_USED(result)) { - ZVAL_TRUE(EX_VAR(result->result.var)); + if (RETURN_VALUE_USED(opline)) { + ZVAL_TRUE(EX_VAR(opline->result.var)); } ZEND_VM_JMP(target); } else { @@ -7824,7 +8056,7 @@ ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, ANY) } } -ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, ANY, ANY) +ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, ANY, ANY, CLASS_FETCH) { uint32_t fetch_type; USE_OPLINE @@ -7957,7 +8189,7 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY) ZEND_ASSERT( EG(exception) || !call->func || !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var))); + zend_verify_internal_return_type(call->func, ret)); #endif EG(current_execute_data) = call->prev_execute_data; @@ -7997,4 +8229,490 @@ ZEND_VM_C_LABEL(call_trampoline_end): ZEND_VM_LEAVE(); } +ZEND_VM_HANDLER(182, ZEND_BIND_LEXICAL, TMP, CV, REF) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *closure, *var; + zend_string *var_name; + + closure = GET_OP1_ZVAL_PTR(BP_VAR_R); + if (opline->extended_value) { + /* By-ref binding */ + var = GET_OP2_ZVAL_PTR(BP_VAR_W); + ZVAL_MAKE_REF(var); + Z_ADDREF_P(var); + } else { + var = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + if (UNEXPECTED(Z_ISUNDEF_P(var))) { + SAVE_OPLINE(); + var = GET_OP2_UNDEF_CV(var, BP_VAR_R); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + ZVAL_DEREF(var); + Z_TRY_ADDREF_P(var); + } + + var_name = CV_DEF_OF(EX_VAR_TO_NUM(opline->op2.var)); + zend_closure_bind_var(closure, var_name, var); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, CONST, REF) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + HashTable *ht; + zval *varname; + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); + zval_ptr_dtor(variable_ptr); + + ht = EX(func)->op_array.static_variables; + ZEND_ASSERT(ht != NULL); + if (GC_REFCOUNT(ht) > 1) { + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_REFCOUNT(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)); + + if (opline->extended_value) { + if (Z_CONSTANT_P(value)) { + if (UNEXPECTED(zval_update_constant_ex(value, 1, NULL) != SUCCESS)) { + ZVAL_NULL(variable_ptr); + HANDLE_EXCEPTION(); + } + } + if (UNEXPECTED(!Z_ISREF_P(value))) { + zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference)); + GC_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; + ZVAL_REF(variable_ptr, ref); + } else { + Z_ADDREF_P(value); + ZVAL_REF(variable_ptr, Z_REF_P(value)); + } + } else { + ZVAL_COPY(variable_ptr, value); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_ADD, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_ADD_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE)) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_ADD, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_ADD_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE)) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = EX_VAR(opline->result.var); + fast_long_add_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_ADD, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_ADD_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE)) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_SUB, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_SUB_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST)) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_SUB, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_SUB_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST)) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = EX_VAR(opline->result.var); + fast_long_sub_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_SUB, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_SUB_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST)) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_MUL, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_MUL_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE)) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) * Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_MUL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_MUL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE)) +{ + USE_OPLINE + zval *op1, *op2, *result; + zend_long overflow; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + 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(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_MUL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_MUL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE)) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE)) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE)) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_NOT_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE)) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_NOT_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE)) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_SMALLER_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST)) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_SMALLER_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST)) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER_OR_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_SMALLER_OR_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST)) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER_OR_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_SMALLER_OR_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST)) +{ + USE_OPLINE + zval *op1, *op2; + int result; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_INC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_PRE_INC_LONG_NO_OVERFLOW, TMPVARCV, ANY, SPEC(RETVAL)) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); + Z_LVAL_P(var_ptr)++; + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + } + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_INC, (op1_info == MAY_BE_LONG), ZEND_PRE_INC_LONG, TMPVARCV, ANY, SPEC(RETVAL)) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); + fast_long_increment_function(var_ptr); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_INC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_PRE_INC_LONG_OR_DOUBLE, TMPVARCV, ANY, SPEC(RETVAL)) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_increment_function(var_ptr); + } else { + Z_DVAL_P(var_ptr)++; + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_DEC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_PRE_DEC_LONG_NO_OVERFLOW, TMPVARCV, ANY, SPEC(RETVAL)) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); + Z_LVAL_P(var_ptr)--; + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + } + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_DEC, (op1_info == MAY_BE_LONG), ZEND_PRE_DEC_LONG, TMPVARCV, ANY, SPEC(RETVAL)) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); + fast_long_decrement_function(var_ptr); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_DEC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_PRE_DEC_LONG_OR_DOUBLE, TMPVARCV, ANY, SPEC(RETVAL)) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_decrement_function(var_ptr); + } else { + Z_DVAL_P(var_ptr)--; + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_INC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_POST_INC_LONG_NO_OVERFLOW, TMPVARCV, ANY) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + Z_LVAL_P(var_ptr)++; + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_INC, (op1_info == MAY_BE_LONG), ZEND_POST_INC_LONG, TMPVARCV, ANY) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + fast_long_increment_function(var_ptr); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_INC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_POST_INC_LONG_OR_DOUBLE, TMPVARCV, ANY) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); + 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(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_DEC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_POST_DEC_LONG_NO_OVERFLOW, TMPVARCV, ANY) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + Z_LVAL_P(var_ptr)--; + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_DEC, (op1_info == MAY_BE_LONG), ZEND_POST_DEC_LONG, TMPVARCV, ANY) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + fast_long_decrement_function(var_ptr); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_DEC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_POST_DEC_LONG_OR_DOUBLE, TMPVARCV, ANY) +{ + USE_OPLINE + zval *var_ptr; + + var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); + 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(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_QM_ASSIGN, (op1_info == MAY_BE_DOUBLE), ZEND_QM_ASSIGN_DOUBLE, CONST|TMPVARCV, ANY) +{ + USE_OPLINE + zend_free_op free_op1; + zval *value; + + value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + ZVAL_DOUBLE(EX_VAR(opline->result.var), Z_DVAL_P(value)); + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_QM_ASSIGN, (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE)))), ZEND_QM_ASSIGN_NOREF, CONST|TMPVARCV, ANY) +{ + USE_OPLINE + zend_free_op free_op1; + zval *value; + + value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + ZEND_VM_NEXT_OPCODE(); +} + ZEND_VM_DEFINE_OP(137, ZEND_OP_DATA); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index bdc1bd7df4..ac7ac1580e 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -306,7 +306,17 @@ static zend_uchar zend_user_opcodes[256] = {0, 241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 }; +#define SPEC_START_MASK 0x0000ffff +#define SPEC_RULE_OP1 0x00010000 +#define SPEC_RULE_OP2 0x00020000 +#define SPEC_RULE_OP_DATA 0x00040000 +#define SPEC_RULE_RETVAL 0x00080000 +#define SPEC_RULE_QUICK_ARG 0x00100000 +#define SPEC_RULE_SMART_BRANCH 0x00200000 + +static const uint32_t *zend_spec_handlers; static const void **zend_opcode_handlers; +static int zend_handlers_count; static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op); @@ -408,7 +418,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) while (1) { #if !defined(ZEND_VM_FP_GLOBAL_REG) || !defined(ZEND_VM_IP_GLOBAL_REG) - int ret; + int ret; #endif #if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG) ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -481,13 +491,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ object = Z_OBJ(old_execute_data->This); #if 0 if (UNEXPECTED(EG(exception) != NULL) && (EX(opline)->op1.num & ZEND_CALL_CTOR)) { - if (!(EX(opline)->op1.num & ZEND_CALL_CTOR_RESULT_UNUSED)) { #else if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { - if (!(call_info & ZEND_CALL_CTOR_RESULT_UNUSED)) { #endif - GC_REFCOUNT(object)--; - } + GC_REFCOUNT(object)--; if (GC_REFCOUNT(object) == 1) { zend_object_store_ctor_failed(object); } @@ -566,12 +573,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_H ZEND_VM_CONTINUE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_execute_data *call = EX(call); zend_function *fbc = call->func; zval *ret; + zval retval; SAVE_OPLINE(); EX(call) = call->prev_execute_data; @@ -579,7 +587,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_HANDLER(ZEND_OPC call->prev_execute_data = execute_data; EG(current_execute_data) = call; - ret = EX_VAR(opline->result.var); + ret = 0 ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); Z_VAR_FLAGS_P(ret) = 0; @@ -589,20 +597,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_HANDLER(ZEND_OPC ZEND_ASSERT( EG(exception) || !call->func || !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var))); + zend_verify_internal_return_type(call->func, ret)); #endif EG(current_execute_data) = call->prev_execute_data; zend_vm_stack_free_args(call); zend_vm_stack_free_call_frame(call); - if (!RETURN_VALUE_USED(opline)) { - zval_ptr_dtor(EX_VAR(opline->result.var)); + if (!0) { + zval_ptr_dtor(ret); } if (UNEXPECTED(EG(exception) != NULL)) { zend_throw_exception_internal(NULL); - if (RETURN_VALUE_USED(opline)) { + if (0) { zval_ptr_dtor(EX_VAR(opline->result.var)); } HANDLE_EXCEPTION(); @@ -612,7 +620,54 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_HANDLER(ZEND_OPC ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; + zval retval; + + SAVE_OPLINE(); + EX(call) = call->prev_execute_data; + + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; + + ret = 1 ? EX_VAR(opline->result.var) : &retval; + ZVAL_NULL(ret); + Z_VAR_FLAGS_P(ret) = 0; + + 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)); +#endif + + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_args(call); + zend_vm_stack_free_call_frame(call); + + if (!1) { + zval_ptr_dtor(ret); + } + + if (UNEXPECTED(EG(exception) != NULL)) { + zend_throw_exception_internal(NULL); + if (1) { + zval_ptr_dtor(EX_VAR(opline->result.var)); + } + HANDLE_EXCEPTION(); + } + + ZEND_VM_INTERRUPT_CHECK(); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_execute_data *call = EX(call); @@ -625,7 +680,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_HANDLER(ZEND_OPC EG(scope) = NULL; ret = NULL; call->symbol_table = NULL; - if (RETURN_VALUE_USED(opline)) { + if (0) { ret = EX_VAR(opline->result.var); ZVAL_NULL(ret); Z_VAR_FLAGS_P(ret) = 0; @@ -637,7 +692,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_HANDLER(ZEND_OPC ZEND_VM_ENTER(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; + + SAVE_OPLINE(); + EX(call) = call->prev_execute_data; + + EG(scope) = NULL; + ret = NULL; + call->symbol_table = NULL; + if (1) { + ret = EX_VAR(opline->result.var); + ZVAL_NULL(ret); + Z_VAR_FLAGS_P(ret) = 0; + } + + call->prev_execute_data = execute_data; + i_init_func_execute_data(call, &fbc->op_array, ret, 0); + + ZEND_VM_ENTER(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_execute_data *call = EX(call); @@ -650,7 +730,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER( if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { EG(scope) = NULL; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) { - if (EXPECTED(RETURN_VALUE_USED(opline))) { + if (EXPECTED(0)) { ret = EX_VAR(opline->result.var); zend_generator_create_zval(call, &fbc->op_array, ret); Z_VAR_FLAGS_P(ret) = 0; @@ -662,7 +742,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER( } else { ret = NULL; call->symbol_table = NULL; - if (RETURN_VALUE_USED(opline)) { + if (0) { ret = EX_VAR(opline->result.var); ZVAL_NULL(ret); Z_VAR_FLAGS_P(ret) = 0; @@ -675,6 +755,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER( } EG(scope) = EX(func)->op_array.scope; } else { + zval retval; ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) { @@ -707,7 +788,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER( } } - ret = EX_VAR(opline->result.var); + ret = 0 ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0; @@ -717,21 +798,125 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER( ZEND_ASSERT( EG(exception) || !call->func || !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var))); + zend_verify_internal_return_type(call->func, ret)); #endif EG(current_execute_data) = call->prev_execute_data; zend_vm_stack_free_args(call); zend_vm_stack_free_call_frame(call); - if (!RETURN_VALUE_USED(opline)) { + if (!0) { + zval_ptr_dtor(ret); + } + } + + if (UNEXPECTED(EG(exception) != NULL)) { + zend_throw_exception_internal(NULL); + if (0) { zval_ptr_dtor(EX_VAR(opline->result.var)); } + HANDLE_EXCEPTION(); + } + ZEND_VM_INTERRUPT_CHECK(); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; + + SAVE_OPLINE(); + EX(call) = call->prev_execute_data; + + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { + EG(scope) = NULL; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) { + if (EXPECTED(1)) { + ret = EX_VAR(opline->result.var); + zend_generator_create_zval(call, &fbc->op_array, ret); + Z_VAR_FLAGS_P(ret) = 0; + } else { + zend_vm_stack_free_args(call); + } + + zend_vm_stack_free_call_frame(call); + } else { + ret = NULL; + call->symbol_table = NULL; + if (1) { + ret = EX_VAR(opline->result.var); + ZVAL_NULL(ret); + Z_VAR_FLAGS_P(ret) = 0; + } + + call->prev_execute_data = execute_data; + i_init_func_execute_data(call, &fbc->op_array, ret, 0); + + ZEND_VM_ENTER(); + } + EG(scope) = EX(func)->op_array.scope; + } else { + zval retval; + ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); + + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) { + zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated", + fbc->common.scope ? ZSTR_VAL(fbc->common.scope->name) : "", + fbc->common.scope ? "::" : "", + ZSTR_VAL(fbc->common.function_name)); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; + + if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) { + uint32_t i; + uint32_t num_args = ZEND_CALL_NUM_ARGS(call); + zval *p = ZEND_CALL_ARG(call, 1); + + for (i = 0; i < num_args; ++i) { + if (UNEXPECTED(!zend_verify_internal_arg_type(fbc, i + 1, p))) { + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_args(call); + zend_vm_stack_free_call_frame(call); + zend_throw_exception_internal(NULL); + HANDLE_EXCEPTION(); + } + p++; + } + } + + ret = 1 ? EX_VAR(opline->result.var) : &retval; + ZVAL_NULL(ret); + Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0; + + 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)); +#endif + + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_args(call); + zend_vm_stack_free_call_frame(call); + + if (!1) { + zval_ptr_dtor(ret); + } } if (UNEXPECTED(EG(exception) != NULL)) { zend_throw_exception_internal(NULL); - if (RETURN_VALUE_USED(opline)) { + if (1) { zval_ptr_dtor(EX_VAR(opline->result.var)); } HANDLE_EXCEPTION(); @@ -740,7 +925,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER( ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_execute_data *call = EX(call); @@ -771,7 +956,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPC if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { EG(scope) = fbc->common.scope; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) { - if (EXPECTED(RETURN_VALUE_USED(opline))) { + if (EXPECTED(0)) { ret = EX_VAR(opline->result.var); zend_generator_create_zval(call, &fbc->op_array, ret); Z_VAR_FLAGS_P(ret) = 0; @@ -784,7 +969,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPC } else { ret = NULL; call->symbol_table = NULL; - if (RETURN_VALUE_USED(opline)) { + if (0) { ret = EX_VAR(opline->result.var); ZVAL_NULL(ret); Z_VAR_FLAGS_P(ret) = 0; @@ -802,6 +987,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPC } } else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) { int should_change_scope = 0; + zval retval; if (fbc->common.scope) { should_change_scope = 1; @@ -820,7 +1006,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPC if (UNEXPECTED(!zend_verify_internal_arg_type(fbc, i + 1, p))) { EG(current_execute_data) = call->prev_execute_data; zend_vm_stack_free_args(call); - if (RETURN_VALUE_USED(opline)) { + if (0) { ZVAL_UNDEF(EX_VAR(opline->result.var)); } if (UNEXPECTED(should_change_scope)) { @@ -833,7 +1019,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPC } } - ret = EX_VAR(opline->result.var); + ret = 0 ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0; @@ -848,14 +1034,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPC ZEND_ASSERT( EG(exception) || !call->func || !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var))); + zend_verify_internal_return_type(call->func, ret)); #endif EG(current_execute_data) = call->prev_execute_data; zend_vm_stack_free_args(call); - if (!RETURN_VALUE_USED(opline)) { - zval_ptr_dtor(EX_VAR(opline->result.var)); + if (!0) { + zval_ptr_dtor(ret); } if (UNEXPECTED(should_change_scope)) { @@ -864,6 +1050,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPC goto fcall_end; } } else { /* ZEND_OVERLOADED_FUNCTION */ + zval retval; /* Not sure what should be done here if it's a static method */ object = Z_OBJ(call->This); if (UNEXPECTED(object == NULL)) { @@ -880,11 +1067,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPC EG(scope) = fbc->common.scope; - ZVAL_NULL(EX_VAR(opline->result.var)); + ret = 0 ? EX_VAR(opline->result.var) : &retval; + ZVAL_NULL(ret); call->prev_execute_data = execute_data; EG(current_execute_data) = call; - object->handlers->call_method(fbc->common.function_name, object, call, EX_VAR(opline->result.var)); + object->handlers->call_method(fbc->common.function_name, object, call, ret); EG(current_execute_data) = call->prev_execute_data; zend_vm_stack_free_args(call); @@ -894,10 +1082,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPC } efree(fbc); - if (!RETURN_VALUE_USED(opline)) { - zval_ptr_dtor(EX_VAR(opline->result.var)); + if (!0) { + zval_ptr_dtor(ret); } else { - Z_VAR_FLAGS_P(EX_VAR(opline->result.var)) = 0; + Z_VAR_FLAGS_P(ret) = 0; } } @@ -906,13 +1094,205 @@ fcall_end_change_scope: object = Z_OBJ(call->This); #if 0 if (UNEXPECTED(EG(exception) != NULL) && (opline->op1.num & ZEND_CALL_CTOR)) { - if (!(opline->op1.num & ZEND_CALL_CTOR_RESULT_UNUSED)) { #else if (UNEXPECTED(EG(exception) != NULL) && (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR)) { - if (!(ZEND_CALL_INFO(call) & ZEND_CALL_CTOR_RESULT_UNUSED)) { #endif - GC_REFCOUNT(object)--; + GC_REFCOUNT(object)--; + if (GC_REFCOUNT(object) == 1) { + zend_object_store_ctor_failed(object); } + } + OBJ_RELEASE(object); + } + EG(scope) = EX(func)->op_array.scope; + +fcall_end: + zend_vm_stack_free_call_frame(call); + if (UNEXPECTED(EG(exception) != NULL)) { + zend_throw_exception_internal(NULL); + if (0) { + zval_ptr_dtor(EX_VAR(opline->result.var)); + } + HANDLE_EXCEPTION(); + } + + ZEND_VM_INTERRUPT_CHECK(); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zend_object *object; + zval *ret; + + SAVE_OPLINE(); + EX(call) = call->prev_execute_data; + if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) { + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) { + zend_throw_error(NULL, "Cannot call abstract method %s::%s()", ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name)); + HANDLE_EXCEPTION(); + } + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) { + zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated", + fbc->common.scope ? ZSTR_VAL(fbc->common.scope->name) : "", + fbc->common.scope ? "::" : "", + ZSTR_VAL(fbc->common.function_name)); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + } + + LOAD_OPLINE(); + + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { + EG(scope) = fbc->common.scope; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) { + if (EXPECTED(1)) { + ret = EX_VAR(opline->result.var); + zend_generator_create_zval(call, &fbc->op_array, ret); + Z_VAR_FLAGS_P(ret) = 0; + } else { + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) { + OBJ_RELEASE((zend_object*)fbc->op_array.prototype); + } + zend_vm_stack_free_args(call); + } + } else { + ret = NULL; + call->symbol_table = NULL; + if (1) { + ret = EX_VAR(opline->result.var); + ZVAL_NULL(ret); + Z_VAR_FLAGS_P(ret) = 0; + } + + call->prev_execute_data = execute_data; + i_init_func_execute_data(call, &fbc->op_array, ret, 1); + + if (EXPECTED(zend_execute_ex == execute_ex)) { + ZEND_VM_ENTER(); + } else { + ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); + zend_execute_ex(call); + } + } + } else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) { + int should_change_scope = 0; + zval retval; + + if (fbc->common.scope) { + should_change_scope = 1; + EG(scope) = fbc->common.scope; + } + + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; + + if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) { + uint32_t i; + uint32_t num_args = ZEND_CALL_NUM_ARGS(call); + zval *p = ZEND_CALL_ARG(call, 1); + + for (i = 0; i < num_args; ++i) { + if (UNEXPECTED(!zend_verify_internal_arg_type(fbc, i + 1, p))) { + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_args(call); + if (1) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + if (UNEXPECTED(should_change_scope)) { + goto fcall_end_change_scope; + } else { + goto fcall_end; + } + } + p++; + } + } + + ret = 1 ? EX_VAR(opline->result.var) : &retval; + ZVAL_NULL(ret); + Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0; + + if (!zend_execute_internal) { + /* saves one function call if zend_execute_internal is not used */ + fbc->internal_function.handler(call, ret); + } else { + zend_execute_internal(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)); +#endif + + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_args(call); + + if (!1) { + zval_ptr_dtor(ret); + } + + if (UNEXPECTED(should_change_scope)) { + goto fcall_end_change_scope; + } else { + goto fcall_end; + } + } else { /* ZEND_OVERLOADED_FUNCTION */ + zval retval; + /* Not sure what should be done here if it's a static method */ + object = Z_OBJ(call->This); + if (UNEXPECTED(object == NULL)) { + zend_vm_stack_free_args(call); + if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) { + zend_string_release(fbc->common.function_name); + } + efree(fbc); + zend_vm_stack_free_call_frame(call); + + zend_throw_error(NULL, "Cannot call overloaded function for non-object"); + HANDLE_EXCEPTION(); + } + + EG(scope) = fbc->common.scope; + + ret = 1 ? EX_VAR(opline->result.var) : &retval; + ZVAL_NULL(ret); + + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; + object->handlers->call_method(fbc->common.function_name, object, call, ret); + EG(current_execute_data) = call->prev_execute_data; + + zend_vm_stack_free_args(call); + + if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) { + zend_string_release(fbc->common.function_name); + } + efree(fbc); + + if (!1) { + zval_ptr_dtor(ret); + } else { + Z_VAR_FLAGS_P(ret) = 0; + } + } + +fcall_end_change_scope: + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) { + object = Z_OBJ(call->This); +#if 0 + if (UNEXPECTED(EG(exception) != NULL) && (opline->op1.num & ZEND_CALL_CTOR)) { +#else + if (UNEXPECTED(EG(exception) != NULL) && (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR)) { +#endif + GC_REFCOUNT(object)--; if (GC_REFCOUNT(object) == 1) { zend_object_store_ctor_failed(object); } @@ -925,7 +1305,7 @@ fcall_end: zend_vm_stack_free_call_frame(call); if (UNEXPECTED(EG(exception) != NULL)) { zend_throw_exception_internal(NULL); - if (RETURN_VALUE_USED(opline)) { + if (1) { zval_ptr_dtor(EX_VAR(opline->result.var)); } HANDLE_EXCEPTION(); @@ -1336,41 +1716,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_SPEC_HANDLER(ZEN ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - SAVE_OPLINE(); - Z_CE_P(EX_VAR(opline->result.var)) = do_bind_inherited_class(&EX(func)->op_array, opline, EG(class_table), Z_CE_P(EX_VAR(opline->extended_value)), 0); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *zce, *orig_zce; - - SAVE_OPLINE(); - if ((zce = zend_hash_find(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op2)))) == NULL || - ((orig_zce = zend_hash_find(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1)))) != 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->extended_value)), 0); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_class_entry *ce; USE_OPLINE SAVE_OPLINE(); - ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op2))); + ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1))); Z_CE_P(EX_VAR(opline->result.var)) = ce; ZEND_ASSERT(ce != NULL); if (ce->ce_flags & ZEND_ACC_ANON_BOUND) { - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op1)); + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLEMENT_INTERFACES|ZEND_ACC_IMPLEMENT_TRAITS))) { @@ -1380,25 +1738,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zend_class_entry *ce; - USE_OPLINE - - SAVE_OPLINE(); - ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op2))); - Z_CE_P(EX_VAR(opline->result.var)) = ce; - ZEND_ASSERT(ce != NULL); - - if (ce->ce_flags & ZEND_ACC_ANON_BOUND) { - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op1)); - } - - zend_do_inheritance(ce, Z_CE_P(EX_VAR(opline->extended_value))); - ce->ce_flags |= ZEND_ACC_ANON_BOUND; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_FUNCTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -1490,7 +1829,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER( * are logically thrown at the end of the foreach loop, so adjust the * op_num. */ - op_num = EX(func)->op_array.brk_cont_array[exc_opline->op2.num].brk; + op_num = EX(func)->op_array.live_range[exc_opline->op2.num].end; } } @@ -1633,7 +1972,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPC const zend_op *fast_ret = EX(func)->op_array.opcodes + fast_call->u2.lineno; ZEND_VM_SET_OPCODE(fast_ret + 1); if (fast_ret->extended_value & ZEND_FAST_CALL_FROM_FINALLY) { - fast_call->u2.lineno = fast_ret->op2.opline_num; + fast_call->u2.lineno = EX(func)->op_array.try_catch_array[fast_ret->op2.num].finally_op - 2; } ZEND_VM_CONTINUE(); } else { @@ -1641,15 +1980,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPC USE_OPLINE if (opline->extended_value == ZEND_FAST_RET_TO_FINALLY) { - cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, opline->op2.opline_num); - ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]); + uint32_t finally_op = EX(func)->op_array.try_catch_array[opline->op2.num].finally_op; + + cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, finally_op); + ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[finally_op]); ZEND_VM_CONTINUE(); } else { EG(exception) = Z_OBJ_P(fast_call); Z_OBJ_P(fast_call) = NULL; if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) { - cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, opline->op2.opline_num); - ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]); + uint32_t catch_op = EX(func)->op_array.try_catch_array[opline->op2.num].catch_op; + + cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, catch_op); + ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op]); ZEND_VM_CONTINUE(); } else { cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, 0); @@ -1671,10 +2014,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSERT_CHECK_SPEC_HANDLER(ZEND if (EG(assertions) <= 0) { zend_op *target = OP_JMP_ADDR(opline, opline->op2); - zend_op *result = target - 1; - SKIP_EXT_OPLINE(result); - if (RETURN_VALUE_USED(result)) { - ZVAL_TRUE(EX_VAR(result->result.var)); + if (RETURN_VALUE_USED(opline)) { + ZVAL_TRUE(EX_VAR(opline->result.var)); } ZEND_VM_JMP(target); } else { @@ -1815,7 +2156,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z ZEND_ASSERT( EG(exception) || !call->func || !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var))); + zend_verify_internal_return_type(call->func, ret)); #endif EG(current_execute_data) = call->prev_execute_data; @@ -2263,6 +2604,49 @@ 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_DECLARE_INHERITED_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + SAVE_OPLINE(); + Z_CE_P(EX_VAR(opline->result.var)) = do_bind_inherited_class(&EX(func)->op_array, opline, EG(class_table), Z_CE_P(EX_VAR(opline->op2.var)), 0); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + 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 && + 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); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_class_entry *ce; + USE_OPLINE + + SAVE_OPLINE(); + ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1))); + 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); + ZEND_VM_CONTINUE(); + } + + zend_do_inheritance(ce, Z_CE_P(EX_VAR(opline->op2.var))); + ce->ce_flags |= ZEND_ACC_ANON_BOUND; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -2839,7 +3223,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CONST_HANDLER(ZE 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 (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + if (IS_CONST == 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(); @@ -3085,14 +3469,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND ZVAL_NULL(EX(return_value)); } } else if (!EX(return_value)) { - if (IS_CONST == IS_VAR || IS_CONST == IS_TMP_VAR ) { + if (IS_CONST & (IS_VAR|IS_TMP_VAR)) { if (Z_REFCOUNTED_P(free_op1) && !Z_DELREF_P(free_op1)) { SAVE_OPLINE(); zval_dtor_func_for_ptr(Z_COUNTED_P(free_op1)); } } } else { - if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); if (IS_CONST == IS_CONST) { if (UNEXPECTED(Z_OPT_COPYABLE_P(EX(return_value)))) { @@ -3130,7 +3514,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDL SAVE_OPLINE(); do { - if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR || + if ((IS_CONST & (IS_CONST|IS_TMP_VAR)) || (IS_CONST == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { /* Not supposed to happen, but we'll allow it */ zend_error(E_NOTICE, "Only variable references should be returned by reference"); @@ -3152,11 +3536,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDL retval_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(retval_ptr == NULL)) { - zend_throw_error(NULL, "Cannot return string offsets by reference"); - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_VAR) { if (retval_ptr == &EG(uninitialized_zval) || (opline->extended_value == ZEND_RETURNS_FUNCTION && @@ -3194,7 +3573,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_CONST_HA retval = EX_CONSTANT(opline->op1); /* Copy return value into generator->retval */ - if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { ZVAL_COPY_VALUE(&generator->retval, retval); if (IS_CONST == IS_CONST) { if (UNEXPECTED(Z_OPT_COPYABLE(generator->retval))) { @@ -3291,7 +3670,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_CONST_HANDLER uint32_t arg_num = opline->op2.num; - if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { + if (EXPECTED(0)) { + if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_val_by_ref; + } + } else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { +send_val_by_ref: + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot pass parameter %d by reference", arg_num); + + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + ZVAL_UNDEF(arg); + HANDLE_EXCEPTION(); + } + value = EX_CONSTANT(opline->op1); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + ZVAL_COPY_VALUE(arg, value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(arg))) { + zval_copy_ctor_func(arg); + } + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_CONST_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value, *arg; + + uint32_t arg_num = opline->op2.num; + + if (EXPECTED(1)) { if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { goto send_val_by_ref; } @@ -3326,7 +3736,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_O 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 (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + if (IS_CONST == 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(); @@ -3343,9 +3753,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_O static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval object_zval; + zval *result; zend_function *constructor; zend_class_entry *ce; + zend_execute_data *call; SAVE_OPLINE(); if (IS_CONST == IS_CONST) { @@ -3357,39 +3768,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OP } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(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)); + HANDLE_EXCEPTION(); + } } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (UNEXPECTED(object_init_ex(&object_zval, ce) != SUCCESS)) { + + result = EX_VAR(opline->result.var); + if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { HANDLE_EXCEPTION(); } - constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval)); + constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); if (constructor == NULL) { - if (EXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval); - } else { - OBJ_RELEASE(Z_OBJ(object_zval)); + /* 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); } - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + + /* 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 { /* We are not handling overloaded classes right now */ - zend_execute_data *call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR | - (EXPECTED(RETURN_VALUE_USED(opline)) ? 0 : ZEND_CALL_CTOR_RESULT_UNUSED), + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR, constructor, opline->extended_value, ce, - Z_OBJ(object_zval)); - call->prev_execute_data = EX(call); - EX(call) = call; - - if (EXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), &object_zval); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + Z_OBJ_P(result)); + Z_ADDREF_P(result); } + + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -3431,19 +3850,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_ } while (0); ce = Z_OBJCE_P(obj); - clone = ce ? ce->clone : NULL; - clone_call = Z_OBJ_HT_P(obj)->clone_obj; + clone = ce->clone; + clone_call = Z_OBJ_HT_P(obj)->clone_obj; if (UNEXPECTED(clone_call == NULL)) { - if (ce) { - zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); - } else { - zend_throw_error(NULL, "Trying to clone an uncloneable object"); - } + zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); HANDLE_EXCEPTION(); } - if (ce && clone) { + 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. */ @@ -3463,11 +3878,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_ } } - if (EXPECTED(EG(exception) == NULL)) { - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); - if (UNEXPECTED(!RETURN_VALUE_USED(opline)) || UNEXPECTED(EG(exception) != NULL)) { - OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); - } + ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); + if (UNEXPECTED(EG(exception) != NULL)) { + OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -4253,7 +4666,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CONST_HANDLER( if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { zend_class_entry *ce = Z_OBJCE_P(value); - if (UNEXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) || + if (EXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) || EXPECTED(memcmp(ZSTR_VAL(ce->name), "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) { result = 1; } @@ -4286,7 +4699,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DEFINED_SPEC_CONST_HANDLER(ZEN result = 1; } else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op1), 0)) == NULL) { result = 0; - ZVAL_FALSE(EX_VAR(opline->result.var)); } else { CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), c); result = 1; @@ -4296,6 +4708,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DEFINED_SPEC_CONST_HANDLER(ZEN ZEND_VM_NEXT_OPCODE(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *value; + + value = EX_CONSTANT(opline->op1); + ZVAL_DOUBLE(EX_VAR(opline->result.var), Z_DVAL_P(value)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_NOREF_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *value; + + value = EX_CONSTANT(opline->op1); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -4933,14 +5367,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_CONST_HAND ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_CONST_CONST(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE zval *varname; zval *retval; zend_string *name; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); varname = EX_CONSTANT(opline->op1); @@ -4957,119 +5391,73 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = 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)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } + if (IS_CONST == IS_CONST) { + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto fetch_var_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)) { - if (IS_CONST != IS_CONST) { - zend_string_release(name); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CONST == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); + goto fetch_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)) { + if (IS_CONST != IS_CONST) { + zend_string_release(name); } - goto fetch_var_return; - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - if (IS_CONST != IS_CONST) { - zend_string_release(name); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - - HANDLE_EXCEPTION(); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - if (IS_CONST == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); - } - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { - 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) { - 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 (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) { + zend_string_release(name); } + + HANDLE_EXCEPTION(); } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + if (IS_CONST == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - HANDLE_EXCEPTION(); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + goto fetch_static_prop_return; } } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + if (IS_CONST != IS_CONST) { + zend_string_release(name); + } + + HANDLE_EXCEPTION(); + } + if (IS_CONST == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } if (IS_CONST != IS_CONST) { zend_string_release(name); } -fetch_var_return: +fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -5082,40 +5470,40 @@ fetch_var_return: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CONST_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_var_address_helper_SPEC_CONST_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -5155,21 +5543,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_ SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); HANDLE_EXCEPTION(); } container = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -5351,21 +5734,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_ HANDLE_EXCEPTION(); } - if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); HANDLE_EXCEPTION(); } - if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -5378,26 +5756,76 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CONST_CONST_HA { USE_OPLINE + zval *container; + zval *offset = EX_CONSTANT(opline->op2); SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); try_fetch_list: if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - zval *value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2))); + zval *value; + zend_string *str; + zend_ulong hval; - if (UNEXPECTED(value == NULL)) { - zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2))); - ZVAL_NULL(EX_VAR(opline->result.var)); +assign_again_list: + if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_list: + value = zend_hash_index_find(Z_ARRVAL_P(container), hval); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_list; + } + +str_index_list: + value = zend_hash_find(Z_ARRVAL_P(container), str); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str)); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (UNEXPECTED(str != Z_STR_P(offset))) { + zend_string_release(str); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto assign_again_list; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index_list; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset)); + hval = Z_RES_HANDLE_P(offset); } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); + zend_error(E_WARNING, "Illegal offset type"); } } else if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) && EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) { zval *result = EX_VAR(opline->result.var); - zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, EX_CONSTANT(opline->op2), BP_VAR_R, result); + zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result); if (retval) { if (result != retval) { @@ -5415,6 +5843,7 @@ try_fetch_list: } ZVAL_NULL(EX_VAR(opline->result.var)); } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -5629,6 +6058,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(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)); + + HANDLE_EXCEPTION(); + } } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -5729,10 +6165,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } } - if (IS_CONST != IS_CONST) { + if (IS_CONST == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -5877,110 +6313,85 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER( ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zend_class_entry *ce; + zend_class_constant *c; + zval *value; USE_OPLINE SAVE_OPLINE(); - if (IS_CONST == IS_UNUSED) { - 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 ((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_NOTICE, "Use of undefined constant %s - assumed '%s'", - 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))); - 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 - } else { - /* class constant */ - zend_class_entry *ce; - zval *value; - 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))); - ZVAL_DEREF(value); + 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))); + 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)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); - } - HANDLE_EXCEPTION(); + 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)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(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)); + HANDLE_EXCEPTION(); } } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); - if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { - ZVAL_DEREF(value); - break; - } } + if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { + break; + } + } - if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { - ZVAL_DEREF(value); - if (Z_CONSTANT_P(value)) { - EG(scope) = ce; - zval_update_constant_ex(value, 1, NULL); - EG(scope) = EX(func)->op_array.scope; - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - if (IS_CONST == 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); + if (EXPECTED((c = zend_hash_find_ptr(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { + if (!zend_verify_const_access(c, EG(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))); + HANDLE_EXCEPTION(); + } + value = &c->value; + if (Z_CONSTANT_P(value)) { + EG(scope) = ce; + zval_update_constant_ex(value, 1, NULL); + EG(scope) = EX(func)->op_array.scope; + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } + } + if (IS_CONST == IS_CONST) { + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); } else { - zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); } - } 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); + zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + HANDLE_EXCEPTION(); } -#else + } 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); -#endif } +#else + ZVAL_COPY(EX_VAR(opline->result.var), value); +#endif + ZEND_VM_NEXT_OPCODE(); } @@ -5994,11 +6405,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); @@ -6114,40 +6520,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CONST_HA } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval tmp, *varname; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); - if (IS_CONST == IS_CV && - IS_CONST == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - zval *var = EX_VAR(opline->op1.var); - - if (Z_REFCOUNTED_P(var)) { - zend_refcounted *garbage = Z_COUNTED_P(var); - - if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); - zval_dtor_func_for_ptr(garbage); - } else { - zval *z = var; - ZVAL_DEREF(z); - if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) { - ZVAL_UNDEF(var); - gc_possible_root(Z_COUNTED_P(z)); - } else { - ZVAL_UNDEF(var); - } - } - } else { - ZVAL_UNDEF(var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } varname = EX_CONSTANT(opline->op1); @@ -6160,33 +6540,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HAN varname = &tmp; } - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + 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)) { - 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)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - HANDLE_EXCEPTION(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + if (IS_CONST != 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)); + 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_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + + HANDLE_EXCEPTION(); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + zend_std_unset_static_property(ce, Z_STR_P(varname)); if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -6195,103 +6578,87 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HAN ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *value; int result; - if (IS_CONST == IS_CV && - IS_CONST == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - 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))) { - 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(); - } else { - - zval tmp, *varname; - - 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; - } - - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - 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*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + zval tmp, *varname; + zend_class_entry *ce; - goto is_var_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_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CONST == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + 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; + } - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + 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*)); - goto is_var_return; - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; } - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + 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_VM_NEXT_OPCODE_CHECK_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_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } - if (IS_CONST == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + HANDLE_EXCEPTION(); } } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + if (IS_CONST == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } -is_var_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); + goto is_static_prop_return; } + } - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + + if (IS_CONST == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); } + + if (IS_CONST != 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_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -6397,6 +6764,9 @@ num_index_prop: 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; @@ -6540,7 +6910,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER 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_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { + if (IS_CONST & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -6555,12 +6925,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER } else { zval *value_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_CONST == IS_VAR && @@ -6717,7 +7081,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(Z 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_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { + if (IS_CONST & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -6732,12 +7096,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(Z } else { zval *value_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_CONST == IS_VAR && @@ -6867,14 +7225,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VA ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_CONST_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE zval *varname; zval *retval; zend_string *name; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); varname = EX_CONSTANT(opline->op1); @@ -6891,119 +7249,73 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = 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)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } + if (IS_VAR == IS_CONST) { + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto fetch_var_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)) { - if (IS_CONST != IS_CONST) { - zend_string_release(name); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CONST == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - HANDLE_EXCEPTION(); + goto fetch_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)) { + if (IS_CONST != IS_CONST) { + zend_string_release(name); } - goto fetch_var_return; - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - if (IS_CONST != IS_CONST) { - zend_string_release(name); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - - HANDLE_EXCEPTION(); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - if (IS_CONST == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); - } - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { - 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) { - 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 (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) { + zend_string_release(name); } + + HANDLE_EXCEPTION(); } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + if (IS_CONST == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - HANDLE_EXCEPTION(); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + goto fetch_static_prop_return; + } + } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + if (IS_CONST != IS_CONST) { + zend_string_release(name); } + + HANDLE_EXCEPTION(); + } + if (IS_CONST == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); } if (IS_CONST != IS_CONST) { zend_string_release(name); } -fetch_var_return: +fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -7016,76 +7328,50 @@ fetch_var_return: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CONST_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_var_address_helper_SPEC_CONST_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval tmp, *varname; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); - if (IS_CONST == IS_CV && - IS_VAR == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - zval *var = EX_VAR(opline->op1.var); - - if (Z_REFCOUNTED_P(var)) { - zend_refcounted *garbage = Z_COUNTED_P(var); - - if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); - zval_dtor_func_for_ptr(garbage); - } else { - zval *z = var; - ZVAL_DEREF(z); - if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) { - ZVAL_UNDEF(var); - gc_possible_root(Z_COUNTED_P(z)); - } else { - ZVAL_UNDEF(var); - } - } - } else { - ZVAL_UNDEF(var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } varname = EX_CONSTANT(opline->op1); @@ -7098,33 +7384,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDL varname = &tmp; } - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + 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)) { - 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)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - HANDLE_EXCEPTION(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + if (IS_CONST != 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)); + 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_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + + HANDLE_EXCEPTION(); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + zend_std_unset_static_property(ce, Z_STR_P(varname)); if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -7133,103 +7422,87 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDL ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *value; int result; - if (IS_CONST == IS_CV && - IS_VAR == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - 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))) { - 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(); - } else { - - zval tmp, *varname; - - 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; - } - - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - 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*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + zval tmp, *varname; + zend_class_entry *ce; - goto is_var_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_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CONST == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + 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; + } - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + 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*)); - goto is_var_return; - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; } - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + 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_VM_NEXT_OPCODE_CHECK_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_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } - if (IS_CONST == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + HANDLE_EXCEPTION(); } } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + if (IS_CONST == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } -is_var_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); + goto is_static_prop_return; } + } - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + + if (IS_CONST == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); } + + if (IS_CONST != 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_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -7259,7 +7532,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(Z 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_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { + if (IS_CONST & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -7274,12 +7547,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(Z } else { zval *value_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_CONST == IS_VAR && @@ -7397,63 +7664,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_UNUSED == IS_CONST) { - if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = 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)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } - - goto fetch_var_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)) { - if (IS_CONST != IS_CONST) { - zend_string_release(name); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CONST == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } - - goto fetch_var_return; - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - if (IS_CONST != IS_CONST) { - zend_string_release(name); - } - - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + retval = zend_hash_find(target_symbol_table, name); + if (retval == NULL) { + 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() } - - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { + /* 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) { switch (type) { case BP_VAR_R: case BP_VAR_UNSET: @@ -7464,52 +7698,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ 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; + /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + ZVAL_NULL(retval); 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) { - 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_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + } - HANDLE_EXCEPTION(); - } - } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - } } if (IS_CONST != IS_CONST) { zend_string_release(name); } -fetch_var_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -7558,6 +7763,145 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CONST_UNUSED_HAN ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(int type ZEND_OPCODE_HANDLER_ARGS_DC) +{ + USE_OPLINE + + zval *varname; + zval *retval; + zend_string *name; + zend_class_entry *ce; + + SAVE_OPLINE(); + varname = EX_CONSTANT(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); + } 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); + } + + if (IS_UNUSED == IS_CONST) { + if (IS_CONST == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = 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)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); + } + + goto fetch_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)) { + if (IS_CONST != IS_CONST) { + zend_string_release(name); + } + + ZEND_VM_NEXT_OPCODE_CHECK_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_CONST != IS_CONST) { + zend_string_release(name); + } + + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (IS_CONST == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); + } + + goto fetch_static_prop_return; + } + } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + if (IS_CONST != IS_CONST) { + zend_string_release(name); + } + + HANDLE_EXCEPTION(); + } + if (IS_CONST == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } + + if (IS_CONST != IS_CONST) { + zend_string_release(name); + } + +fetch_static_prop_return: + ZEND_ASSERT(retval != NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { + ZVAL_UNREF(retval); + } + ZVAL_COPY(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_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CONST_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_CONST_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } else { + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -7567,21 +7911,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_ SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); HANDLE_EXCEPTION(); } container = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -7625,6 +7964,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(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)); + + HANDLE_EXCEPTION(); + } } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -7725,10 +8071,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } } - if (IS_CONST != IS_CONST) { + if (IS_CONST == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -7789,8 +8135,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_ if (UNEXPECTED(EG(exception) != NULL)) { if (IS_CONST == IS_CONST) { zval_ptr_dtor_nogc(retval_ptr); - } else { - } } #endif @@ -7808,11 +8152,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_U if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); @@ -7937,7 +8276,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HA SAVE_OPLINE(); if (IS_CONST == IS_CV && - IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { zval *var = EX_VAR(opline->op1.var); @@ -7974,33 +8312,66 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HA varname = &tmp; } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); - 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)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } - HANDLE_EXCEPTION(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval tmp, *varname; + 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) { + 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; + } + + 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)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + if (IS_CONST != 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)); + 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_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + + HANDLE_EXCEPTION(); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + zend_std_unset_static_property(ce, Z_STR_P(varname)); if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -8016,7 +8387,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_U int result; if (IS_CONST == IS_CV && - IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { value = EX_VAR(opline->op1.var); if (opline->extended_value & ZEND_ISSET) { @@ -8037,6 +8407,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_U } else { zval tmp, *varname; + HashTable *target_symbol_table; SAVE_OPLINE(); varname = EX_CONSTANT(opline->op1); @@ -8046,55 +8417,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_U varname = &tmp; } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; - - 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*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_var_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_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CONST == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_var_return; - } - } - - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); - - if (IS_CONST == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); - } - } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); - } + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); } -is_var_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); @@ -8108,6 +8437,89 @@ is_var_return: } } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + int result; + + zval tmp, *varname; + 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; + } + + 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*)); + + /* 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_VM_NEXT_OPCODE_CHECK_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_CONST != 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)); + } + if (IS_CONST == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* 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_CONST == IS_CONST && value) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + } + + if (IS_CONST != 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_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -8157,7 +8569,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE 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_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { + if (IS_CONST & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -8172,12 +8584,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE } else { zval *value_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_CONST == IS_VAR && @@ -8945,21 +9351,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_ SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); HANDLE_EXCEPTION(); } container = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var), IS_CV); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -9141,21 +9542,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_ HANDLE_EXCEPTION(); } - if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); HANDLE_EXCEPTION(); } - if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -9164,6 +9560,101 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_ } } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + + zval *container; + zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + + SAVE_OPLINE(); + container = EX_CONSTANT(opline->op1); + +try_fetch_list: + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + zval *value; + zend_string *str; + zend_ulong hval; + +assign_again_list: + if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_list: + value = zend_hash_index_find(Z_ARRVAL_P(container), hval); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_list; + } + +str_index_list: + value = zend_hash_find(Z_ARRVAL_P(container), str); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str)); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (UNEXPECTED(str != Z_STR_P(offset))) { + zend_string_release(str); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto assign_again_list; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index_list; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset)); + hval = Z_RES_HANDLE_P(offset); + } else { + zend_error(E_WARNING, "Illegal offset type"); + } + } else if (IS_CONST != IS_CONST && + UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) && + EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) { + zval *result = EX_VAR(opline->result.var); + zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result); + + if (retval) { + if (result != retval) { + ZVAL_COPY(result, retval); + } + } else { + ZVAL_NULL(result); + } + } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + goto try_fetch_list; + } else { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -9375,6 +9866,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(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)); + + HANDLE_EXCEPTION(); + } } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -9475,10 +9973,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } } - if (IS_CONST != IS_CONST) { + if (IS_CONST == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -9559,8 +10057,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_CV_HANDLER(ZE /* Check whether an exception has been thrown, if not, jump over code */ zend_exception_restore(); if (EG(exception) == NULL) { - ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->extended_value]); - ZEND_VM_CONTINUE(); /* CHECK_ME */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); if (UNEXPECTED(catch_ce == NULL)) { @@ -9582,8 +10080,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_CV_HANDLER(ZE zend_throw_exception_internal(NULL); HANDLE_EXCEPTION(); } - ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->extended_value]); - ZEND_VM_CONTINUE(); /* CHECK_ME */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } } @@ -9683,11 +10181,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); @@ -9906,6 +10399,9 @@ num_index_prop: 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; @@ -10013,7 +10509,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE 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_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { + if (IS_CONST & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -10028,12 +10524,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE } else { zval *value_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_CONST == IS_VAR && @@ -10765,21 +11255,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_ SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { + 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)); HANDLE_EXCEPTION(); } container = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR)); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } zval_ptr_dtor_nogc(free_op2); @@ -10963,21 +11448,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_ zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -10986,6 +11466,101 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_ } } +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; + zval *container; + zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + + SAVE_OPLINE(); + container = EX_CONSTANT(opline->op1); + +try_fetch_list: + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + zval *value; + zend_string *str; + zend_ulong hval; + +assign_again_list: + if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_list: + value = zend_hash_index_find(Z_ARRVAL_P(container), hval); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_list; + } + +str_index_list: + value = zend_hash_find(Z_ARRVAL_P(container), str); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str)); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (UNEXPECTED(str != Z_STR_P(offset))) { + zend_string_release(str); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto assign_again_list; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index_list; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset)); + hval = Z_RES_HANDLE_P(offset); + } else { + zend_error(E_WARNING, "Illegal offset type"); + } + } else if (IS_CONST != IS_CONST && + UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) && + EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) { + zval *result = EX_VAR(opline->result.var); + zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result); + + if (retval) { + if (result != retval) { + ZVAL_COPY(result, retval); + } + } else { + ZVAL_NULL(result); + } + } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + goto try_fetch_list; + } else { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + ZVAL_NULL(EX_VAR(opline->result.var)); + } + 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 @@ -11198,6 +11773,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(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)); } @@ -11298,10 +11880,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C } } - if (IS_CONST != IS_CONST) { + if (IS_CONST == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -11457,11 +12039,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_T if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); @@ -11680,6 +12257,9 @@ num_index_prop: 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; @@ -11761,6 +12341,452 @@ isset_no_object: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_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(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_SPEC_CONST_TMPVARCV_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); + fast_long_add_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_DOUBLE_SPEC_CONST_TMPVARCV_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(); +} + +static 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 = 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(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_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); + fast_long_sub_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_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(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_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(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_LONG_SPEC_CONST_TMPVARCV_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(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_DOUBLE_SPEC_CONST_TMPVARCV_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(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + 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)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + 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_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + 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(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + 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)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + 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(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + 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(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + 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)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + 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_JMPZ(result, 0); + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + 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(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + 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)); + + ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + 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(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + 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(); +} + +static 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 = EX_CONSTANT(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_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 = 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(); +} + +static 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 = 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(); +} + +static 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 = EX_CONSTANT(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_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 = 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(); +} + +static 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 = 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(); +} + +static 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 = EX_CONSTANT(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_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 = 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(); +} + +static 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 = 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(); +} + +static 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 = EX_CONSTANT(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_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 = 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(); +} + +static 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 = 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(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -11775,14 +12801,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_O ZVAL_NULL(EX(return_value)); } } else if (!EX(return_value)) { - if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_TMP_VAR ) { + if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) { if (Z_REFCOUNTED_P(free_op1) && !Z_DELREF_P(free_op1)) { SAVE_OPLINE(); zval_dtor_func_for_ptr(Z_COUNTED_P(free_op1)); } } } else { - if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); if (IS_TMP_VAR == IS_CONST) { if (UNEXPECTED(Z_OPT_COPYABLE_P(EX(return_value)))) { @@ -11820,7 +12846,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER SAVE_OPLINE(); do { - if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR || + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) || (IS_TMP_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { /* Not supposed to happen, but we'll allow it */ zend_error(E_NOTICE, "Only variable references should be returned by reference"); @@ -11842,11 +12868,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER retval_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(retval_ptr == NULL)) { - zend_throw_error(NULL, "Cannot return string offsets by reference"); - HANDLE_EXCEPTION(); - } - if (IS_TMP_VAR == IS_VAR) { if (retval_ptr == &EG(uninitialized_zval) || (opline->extended_value == ZEND_RETURNS_FUNCTION && @@ -11884,7 +12905,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_TMP_HAND retval = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); /* Copy return value into generator->retval */ - if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { ZVAL_COPY_VALUE(&generator->retval, retval); if (IS_TMP_VAR == IS_CONST) { if (UNEXPECTED(Z_OPT_COPYABLE(generator->retval))) { @@ -11981,7 +13002,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_TMP_HANDLER(Z zend_free_op free_op1; uint32_t arg_num = opline->op2.num; - if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { + if (EXPECTED(0)) { + if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_val_by_ref; + } + } else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { +send_val_by_ref: + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot pass parameter %d by reference", arg_num); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + ZVAL_UNDEF(arg); + HANDLE_EXCEPTION(); + } + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + ZVAL_COPY_VALUE(arg, value); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(arg))) { + zval_copy_ctor_func(arg); + } + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_TMP_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value, *arg; + zend_free_op free_op1; + uint32_t arg_num = opline->op2.num; + + if (EXPECTED(1)) { if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { goto send_val_by_ref; } @@ -12599,7 +13651,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_TMP_HANDLER(ZE if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { zend_class_entry *ce = Z_OBJCE_P(value); - if (UNEXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) || + if (EXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) || EXPECTED(memcmp(ZSTR_VAL(ce->name), "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) { result = 1; } @@ -12667,21 +13719,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CO SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { + 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->op1.var)); HANDLE_EXCEPTION(); } container = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -12791,21 +13838,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CO HANDLE_EXCEPTION(); } - if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); HANDLE_EXCEPTION(); } - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -12910,11 +13952,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CON if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); @@ -13057,7 +14094,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(Z 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_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { + if (IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -13072,12 +14109,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(Z } else { zval *value_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_TMP_VAR == IS_VAR && @@ -13234,7 +14265,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEN 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_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { + if (IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -13249,12 +14280,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEN } else { zval *value_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_TMP_VAR == IS_VAR && @@ -13411,7 +14436,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEN 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_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { + if (IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -13426,12 +14451,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEN } else { zval *value_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_TMP_VAR == IS_VAR && @@ -13534,21 +14553,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UN SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { + 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->op1.var)); HANDLE_EXCEPTION(); } container = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -13615,8 +14629,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN if (UNEXPECTED(EG(exception) != NULL)) { if (IS_TMP_VAR == IS_CONST) { zval_ptr_dtor_nogc(retval_ptr); - } else { - zval_ptr_dtor_nogc(free_op1); } } #endif @@ -13634,11 +14646,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNU if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); @@ -13781,7 +14788,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER( 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_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { + if (IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -13796,12 +14803,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER( } else { zval *value_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_TMP_VAR == IS_VAR && @@ -13940,21 +14941,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { + 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->op1.var)); HANDLE_EXCEPTION(); } container = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var), IS_CV); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -14064,21 +15060,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV HANDLE_EXCEPTION(); } - if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); HANDLE_EXCEPTION(); } - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -14183,11 +15174,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_ if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); @@ -14330,7 +15316,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND 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_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { + if (IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -14345,12 +15331,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND } else { zval *value_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_TMP_VAR == IS_VAR && @@ -14444,6 +15424,37 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND ZEND_VM_RETURN(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_LEXICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *closure, *var; + zend_string *var_name; + + closure = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + if (opline->extended_value) { + /* By-ref binding */ + var = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op2.var); + ZVAL_MAKE_REF(var); + Z_ADDREF_P(var); + } else { + var = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); + if (UNEXPECTED(Z_ISUNDEF_P(var))) { + SAVE_OPLINE(); + var = GET_OP2_UNDEF_CV(var, BP_VAR_R); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + ZVAL_DEREF(var); + Z_TRY_ADDREF_P(var); + } + + var_name = CV_DEF_OF(EX_VAR_TO_NUM(opline->op2.var)); + zend_closure_bind_var(closure, var_name, var); + 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 @@ -14453,21 +15464,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TM SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { + 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)); HANDLE_EXCEPTION(); } container = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR)); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } zval_ptr_dtor_nogc(free_op2); @@ -14578,21 +15584,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TM zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -14697,11 +15698,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); @@ -14817,7 +15813,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HAN } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op1; @@ -14825,22 +15821,56 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - HANDLE_EXCEPTION(); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_increment_function(var_ptr); + if (UNEXPECTED(0)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); } + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { + if (UNEXPECTED(0)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { + var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); + } + ZVAL_DEREF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); + + increment_function(var_ptr); + + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + } + + 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_SPEC_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *var_ptr; + + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { fast_long_increment_function(var_ptr); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(1)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); } ZEND_VM_NEXT_OPCODE(); } - if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { + if (UNEXPECTED(1)) { ZVAL_NULL(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE(); @@ -14855,7 +15885,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_ increment_function(var_ptr); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(1)) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } @@ -14863,7 +15893,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op1; @@ -14871,22 +15901,56 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - HANDLE_EXCEPTION(); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_decrement_function(var_ptr); + if (UNEXPECTED(0)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); } + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { + if (UNEXPECTED(0)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { + var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); + } + ZVAL_DEREF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); + + decrement_function(var_ptr); + + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + } + + 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_DEC_SPEC_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *var_ptr; + + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { fast_long_decrement_function(var_ptr); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(1)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); } ZEND_VM_NEXT_OPCODE(); } - if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { + if (UNEXPECTED(1)) { ZVAL_NULL(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE(); @@ -14901,7 +15965,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_ decrement_function(var_ptr); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(1)) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } @@ -14917,19 +15981,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - HANDLE_EXCEPTION(); - } - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); fast_long_increment_function(var_ptr); ZEND_VM_NEXT_OPCODE(); } - if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); ZEND_VM_NEXT_OPCODE(); } @@ -14956,19 +16014,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - HANDLE_EXCEPTION(); - } - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); fast_long_decrement_function(var_ptr); ZEND_VM_NEXT_OPCODE(); } - if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); ZEND_VM_NEXT_OPCODE(); } @@ -15001,14 +16053,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_O ZVAL_NULL(EX(return_value)); } } else if (!EX(return_value)) { - if (IS_VAR == IS_VAR || IS_VAR == IS_TMP_VAR ) { + if (IS_VAR & (IS_VAR|IS_TMP_VAR)) { if (Z_REFCOUNTED_P(free_op1) && !Z_DELREF_P(free_op1)) { SAVE_OPLINE(); zval_dtor_func_for_ptr(Z_COUNTED_P(free_op1)); } } } else { - if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { + if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); if (IS_VAR == IS_CONST) { if (UNEXPECTED(Z_OPT_COPYABLE_P(EX(return_value)))) { @@ -15046,7 +16098,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER SAVE_OPLINE(); do { - if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR || + if ((IS_VAR & (IS_CONST|IS_TMP_VAR)) || (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { /* Not supposed to happen, but we'll allow it */ zend_error(E_NOTICE, "Only variable references should be returned by reference"); @@ -15068,11 +16120,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER retval_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(retval_ptr == NULL)) { - zend_throw_error(NULL, "Cannot return string offsets by reference"); - HANDLE_EXCEPTION(); - } - if (IS_VAR == IS_VAR) { if (retval_ptr == &EG(uninitialized_zval) || (opline->extended_value == ZEND_RETURNS_FUNCTION && @@ -15111,7 +16158,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_VAR_HAND retval = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); /* Copy return value into generator->retval */ - if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { + if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { ZVAL_COPY_VALUE(&generator->retval, retval); if (IS_VAR == IS_CONST) { if (UNEXPECTED(Z_OPT_COPYABLE(generator->retval))) { @@ -15269,15 +16316,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND SAVE_OPLINE(); varptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(varptr == NULL)) { - zend_throw_error(NULL, "Only variables can be passed by reference"); - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - ZVAL_UNDEF(arg); - HANDLE_EXCEPTION(); - } - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - if (IS_VAR == IS_VAR && UNEXPECTED(varptr == &EG(error_zval))) { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(varptr))) { ZVAL_NEW_REF(arg, &EG(uninitialized_zval)); ZEND_VM_NEXT_OPCODE(); } @@ -15302,7 +16342,56 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER(Z zend_free_op free_op1; uint32_t arg_num = opline->op2.num; - if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { + if (EXPECTED(0)) { + if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_var_by_ref; + } + } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { +send_var_by_ref: + ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(varptr, BP_VAR_R); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + ZVAL_NULL(arg); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + + if (IS_VAR == IS_CV) { + ZVAL_OPT_DEREF(varptr); + ZVAL_COPY(arg, varptr); + } else /* if (IS_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); + + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); + } + } else { + ZVAL_COPY_VALUE(arg, varptr); + } + } + + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_VAR_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varptr, *arg; + zend_free_op free_op1; + uint32_t arg_num = opline->op2.num; + + if (EXPECTED(1)) { if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { goto send_var_by_ref; } @@ -15402,9 +16491,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEN static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval object_zval; + zval *result; zend_function *constructor; zend_class_entry *ce; + zend_execute_data *call; SAVE_OPLINE(); if (IS_VAR == IS_CONST) { @@ -15416,39 +16506,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCO } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(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)); + HANDLE_EXCEPTION(); + } } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (UNEXPECTED(object_init_ex(&object_zval, ce) != SUCCESS)) { + + result = EX_VAR(opline->result.var); + if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { HANDLE_EXCEPTION(); } - constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval)); + constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); if (constructor == NULL) { - if (EXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval); - } else { - OBJ_RELEASE(Z_OBJ(object_zval)); + /* 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); } - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + + /* 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 { /* We are not handling overloaded classes right now */ - zend_execute_data *call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR | - (EXPECTED(RETURN_VALUE_USED(opline)) ? 0 : ZEND_CALL_CTOR_RESULT_UNUSED), + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR, constructor, opline->extended_value, ce, - Z_OBJ(object_zval)); - call->prev_execute_data = EX(call); - EX(call) = call; - - if (EXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), &object_zval); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + Z_OBJ_P(result)); + Z_ADDREF_P(result); } + + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -15862,7 +16960,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZE break; } Z_FE_POS_P(array) = pos + 1; - if (opline->result_type == IS_TMP_VAR) { + if (opline->result_type & (IS_TMP_VAR|IS_CV)) { if (!p->key) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); } else { @@ -15906,7 +17004,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZE pos++; p++; } - if (opline->result_type == IS_TMP_VAR) { + if (opline->result_type & (IS_TMP_VAR|IS_CV)) { if (UNEXPECTED(!p->key)) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); } else if (ZSTR_VAL(p->key)[0]) { @@ -15941,13 +17039,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZE * In case that ever happens we need an additional flag. */ iter->funcs->move_forward(iter); if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } if (UNEXPECTED(iter->funcs->valid(iter) == FAILURE)) { /* reached end of iteration */ if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } goto fe_fetch_r_exit; @@ -15955,18 +17051,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZE } value = iter->funcs->get_current_data(iter); if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } if (!value) { /* failure in get_current_data */ goto fe_fetch_r_exit; } - if (opline->result_type == IS_TMP_VAR) { + if (opline->result_type & (IS_TMP_VAR|IS_CV)) { if (iter->funcs->get_current_key) { iter->funcs->get_current_key(iter, EX_VAR(opline->result.var)); if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } } else { @@ -16040,7 +17134,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z } break; } - if (opline->result_type == IS_TMP_VAR) { + if (opline->result_type & (IS_TMP_VAR|IS_CV)) { if (!p->key) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); } else { @@ -16098,7 +17192,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z pos++; p++; } - if (opline->result_type == IS_TMP_VAR) { + if (opline->result_type & (IS_TMP_VAR|IS_CV)) { if (UNEXPECTED(!p->key)) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); } else if (ZSTR_VAL(p->key)[0]) { @@ -16133,13 +17227,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z * In case that ever happens we need an additional flag. */ iter->funcs->move_forward(iter); if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } if (UNEXPECTED(iter->funcs->valid(iter) == FAILURE)) { /* reached end of iteration */ if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } goto fe_fetch_w_exit; @@ -16147,18 +17239,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z } value = iter->funcs->get_current_data(iter); if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } if (!value) { /* failure in get_current_data */ goto fe_fetch_w_exit; } - if (opline->result_type == IS_TMP_VAR) { + if (opline->result_type & (IS_TMP_VAR|IS_CV)) { if (iter->funcs->get_current_key) { iter->funcs->get_current_key(iter, EX_VAR(opline->result.var)); if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(array); HANDLE_EXCEPTION(); } } else { @@ -16420,7 +17510,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_VAR_HANDLER(ZE if (IS_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { zend_class_entry *ce = Z_OBJCE_P(value); - if (UNEXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) || + if (EXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) || EXPECTED(memcmp(ZSTR_VAL(ce->name), "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) { result = 1; } @@ -16500,13 +17590,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP property = EX_CONSTANT(opline->op2); - if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - - HANDLE_EXCEPTION(); - } - do { value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); @@ -16524,7 +17607,7 @@ 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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -16564,12 +17647,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - - HANDLE_EXCEPTION(); - } dim = EX_CONSTANT(opline->op2); @@ -16587,22 +17664,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP zend_fetch_dimension_address_RW(&rv, container, dim, IS_CONST); value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - var_ptr = Z_INDIRECT(rv); - - if (UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - FREE_OP(free_op_data1); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); - } - - if (UNEXPECTED(var_ptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR(rv))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { + ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); + var_ptr = Z_INDIRECT(rv); ZVAL_DEREF(var_ptr); SEPARATE_ZVAL_NOREF(var_ptr); @@ -16630,13 +17699,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_V value = EX_CONSTANT(opline->op2); var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - - if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -16914,12 +17977,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE property = EX_CONSTANT(opline->op2); - if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -16935,7 +17992,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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -16998,12 +18055,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP property = EX_CONSTANT(opline->op2); - if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -17018,7 +18069,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP 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(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) { @@ -17067,14 +18118,10 @@ 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, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -17089,14 +18136,10 @@ 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, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -17111,21 +18154,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CO SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { + 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->op1.var)); HANDLE_EXCEPTION(); } container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; @@ -17153,15 +18191,10 @@ 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, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -17255,16 +18288,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HAN HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -17286,15 +18314,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HA HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -17319,21 +18342,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CO HANDLE_EXCEPTION(); } - if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { + if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -17359,26 +18377,370 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST property = EX_CONSTANT(opline->op2); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 0); + 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_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op1; - zval *object; - zval *property_name; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + + HANDLE_EXCEPTION(); + } + + property_name = EX_CONSTANT(opline->op2); + value = EX_CONSTANT((opline+1)->op1); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + } while (0); + } + + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CONST != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CONST == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +exit_assign_obj: + + 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_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op_data; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + + HANDLE_EXCEPTION(); + } + + property_name = EX_CONSTANT(opline->op2); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_TMP_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + zval_ptr_dtor_nogc(free_op_data); + } +exit_assign_obj: + + 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_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op_data; + zval *object, *property_name, *value, tmp; SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); @@ -17390,25 +18752,346 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HAND } property_name = EX_CONSTANT(opline->op2); + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + zval_ptr_dtor_nogc(free_op_data); + } +exit_assign_obj: + + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} - if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); HANDLE_EXCEPTION(); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_VAR, property_name, IS_CONST, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); + + property_name = EX_CONSTANT(opline->op2); + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + } while (0); + } + + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CV != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CV == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +exit_assign_obj: 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_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op1; zval *object_ptr; - zend_free_op free_op_data1; + zval *value; zval *variable_ptr; zval *dim; @@ -17416,12 +19099,101 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HAND SAVE_OPLINE(); object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_CONST == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { + dim = EX_CONSTANT(opline->op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CONST, BP_VAR_W); - HANDLE_EXCEPTION(); + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + 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)) { + + zval *property_name = EX_CONSTANT(opline->op2); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CONST, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_CONST == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = EX_CONSTANT(opline->op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = EX_CONSTANT((opline+1)->op1); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } } + 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_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *object_ptr; + zend_free_op free_op_data; + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: @@ -17430,7 +19202,7 @@ try_assign_dim_array: 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"); - variable_ptr = &EG(error_zval); + variable_ptr = NULL; } } else { dim = EX_CONSTANT(opline->op2); @@ -17438,14 +19210,14 @@ try_assign_dim_array: variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CONST, BP_VAR_W); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - FREE_OP(free_op_data1); + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + 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); } @@ -17461,13 +19233,13 @@ try_assign_dim_array: zval *property_name = EX_CONSTANT(opline->op2); - zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_TMP_VAR, (opline+1)->op1, execute_data); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { if (IS_CONST == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; HANDLE_EXCEPTION(); } else { @@ -17476,9 +19248,9 @@ try_assign_dim_array: dim = EX_CONSTANT(opline->op2); offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); - value = get_zval_ptr_r_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + zval_ptr_dtor_nogc(free_op_data); } } else { zval_ptr_dtor_nogc(object_ptr); @@ -17488,17 +19260,206 @@ assign_dim_convert_to_array: goto try_assign_dim_array; } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) { - goto assign_dim_clean; + goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + 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_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *object_ptr; + zend_free_op free_op_data; + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_CONST == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { + dim = EX_CONSTANT(opline->op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CONST, BP_VAR_W); + + } + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + 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)) { + + zval *property_name = EX_CONSTANT(opline->op2); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_VAR, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_CONST == 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);}; + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = EX_CONSTANT(opline->op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = _get_zval_ptr_var_deref((opline+1)->op1.var, execute_data, &free_op_data); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zval_ptr_dtor_nogc(free_op_data); + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; } else { zend_error(E_WARNING, "Cannot use a scalar value as an array"); assign_dim_clean: + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + 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_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *object_ptr; + + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_CONST == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { dim = EX_CONSTANT(opline->op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CONST, BP_VAR_W); + + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + 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)) { + + zval *property_name = EX_CONSTANT(opline->op2); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CV, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_CONST == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = EX_CONSTANT(opline->op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, (opline+1)->op1.var); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - FREE_OP(free_op_data1); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -17509,7 +19470,7 @@ assign_dim_clean: ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op1; @@ -17520,14 +19481,42 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER( value = EX_CONSTANT(opline->op2); variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(0)) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { value = zend_assign_to_variable(variable_ptr, value, IS_CONST); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + /* 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_VAR_CONST_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + value = EX_CONSTANT(opline->op2); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (IS_VAR == 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_CONST); + if (UNEXPECTED(1)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; @@ -17562,6 +19551,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(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)); + + HANDLE_EXCEPTION(); + } } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -17662,10 +19658,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } } - if (IS_VAR != IS_CONST) { + if (IS_VAR == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -17678,110 +19674,85 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zend_class_entry *ce; + zend_class_constant *c; + zval *value; USE_OPLINE SAVE_OPLINE(); - if (IS_VAR == IS_UNUSED) { - 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 ((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_NOTICE, "Use of undefined constant %s - assumed '%s'", - 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))); - 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 - } else { - /* class constant */ - zend_class_entry *ce; - zval *value; - 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))); - ZVAL_DEREF(value); + 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))); + 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)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); - } - HANDLE_EXCEPTION(); + 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)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + HANDLE_EXCEPTION(); + } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(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)); + HANDLE_EXCEPTION(); } } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); - if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { - ZVAL_DEREF(value); - break; - } } + if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { + break; + } + } - if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { - ZVAL_DEREF(value); - if (Z_CONSTANT_P(value)) { - EG(scope) = ce; - zval_update_constant_ex(value, 1, NULL); - EG(scope) = EX(func)->op_array.scope; - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - if (IS_VAR == 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); + if (EXPECTED((c = zend_hash_find_ptr(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { + if (!zend_verify_const_access(c, EG(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))); + HANDLE_EXCEPTION(); + } + value = &c->value; + if (Z_CONSTANT_P(value)) { + EG(scope) = ce; + zval_update_constant_ex(value, 1, NULL); + EG(scope) = EX(func)->op_array.scope; + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } + } + if (IS_VAR == IS_CONST) { + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); } else { - zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); } - } 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); + zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + HANDLE_EXCEPTION(); } -#else + } 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); -#endif } +#else + ZVAL_COPY(EX_VAR(opline->result.var), value); +#endif + ZEND_VM_NEXT_OPCODE(); } @@ -17795,11 +19766,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CON 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, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; @@ -17931,11 +19897,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDL HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - - HANDLE_EXCEPTION(); - } offset = EX_CONSTANT(opline->op2); do { @@ -18027,11 +19988,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDL HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - - HANDLE_EXCEPTION(); - } offset = EX_CONSTANT(opline->op2); do { @@ -18083,7 +20039,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z 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_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { + if (IS_VAR & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -18098,12 +20054,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z } else { zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_VAR == IS_VAR && @@ -18234,7 +20184,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -18245,14 +20195,42 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZE value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(0)) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + /* 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_VAR_TMP_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (IS_VAR == 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); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; @@ -18289,7 +20267,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEN 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_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { + if (IS_VAR & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -18304,12 +20282,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEN } else { zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_VAR == IS_VAR && @@ -18440,7 +20412,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -18451,14 +20423,42 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZE value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(0)) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { value = zend_assign_to_variable(variable_ptr, value, IS_VAR); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + /* 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_VAR_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (IS_VAR == 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); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; @@ -18477,54 +20477,50 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLE SAVE_OPLINE(); value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets nor overloaded objects"); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && - UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var)))) { + 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);}; HANDLE_EXCEPTION(); - } - if (IS_VAR == IS_VAR && - (value_ptr == &EG(uninitialized_zval) || - (opline->extended_value == ZEND_RETURNS_FUNCTION && - !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) { - if (!(free_op2 != NULL) && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op2.var)) != IS_INDIRECT)) { /* undo the effect of get_zval_ptr_ptr() */ - Z_TRY_ADDREF_P(value_ptr); - } + + } else if (IS_VAR == IS_VAR && + opline->extended_value == ZEND_RETURNS_FUNCTION && + UNEXPECTED(!(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { + 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);}; HANDLE_EXCEPTION(); } - ZEND_VM_TAIL_CALL(ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets nor overloaded objects"); - if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);}; - HANDLE_EXCEPTION(); - } - if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || - (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) { - variable_ptr = &EG(uninitialized_zval); + 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 { - 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 ((IS_VAR == 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);}; } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);}; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -18555,7 +20551,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEN 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_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { + if (IS_VAR & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -18570,12 +20566,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEN } else { zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_VAR == IS_VAR && @@ -18685,12 +20675,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - - HANDLE_EXCEPTION(); - } dim = NULL; @@ -18708,22 +20692,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP zend_fetch_dimension_address_RW(&rv, container, dim, IS_UNUSED); value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - var_ptr = Z_INDIRECT(rv); - if (UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - - FREE_OP(free_op_data1); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); - } - - if (UNEXPECTED(var_ptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR(rv))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { + ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); + var_ptr = Z_INDIRECT(rv); ZVAL_DEREF(var_ptr); SEPARATE_ZVAL_NOREF(var_ptr); @@ -18989,14 +20965,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HA SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -19011,14 +20983,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_H SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -19033,21 +21001,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UN SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { + 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->op1.var)); HANDLE_EXCEPTION(); } container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; @@ -19066,12 +21029,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UN ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op1; zval *object_ptr; - zend_free_op free_op_data1; + zval *value; zval *variable_ptr; zval *dim; @@ -19079,12 +21042,101 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HAN SAVE_OPLINE(); object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_UNUSED == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { + dim = NULL; + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_UNUSED, BP_VAR_W); - HANDLE_EXCEPTION(); + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + 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)) { + + zval *property_name = NULL; + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CONST, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_UNUSED == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = NULL; + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = EX_CONSTANT((opline+1)->op1); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } } + 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_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *object_ptr; + zend_free_op free_op_data; + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: @@ -19093,7 +21145,7 @@ try_assign_dim_array: 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"); - variable_ptr = &EG(error_zval); + variable_ptr = NULL; } } else { dim = NULL; @@ -19101,14 +21153,14 @@ try_assign_dim_array: variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_UNUSED, BP_VAR_W); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - FREE_OP(free_op_data1); + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + 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); } @@ -19124,13 +21176,13 @@ try_assign_dim_array: zval *property_name = NULL; - zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_TMP_VAR, (opline+1)->op1, execute_data); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { if (IS_UNUSED == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; HANDLE_EXCEPTION(); } else { @@ -19139,9 +21191,9 @@ try_assign_dim_array: dim = NULL; offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); - value = get_zval_ptr_r_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + zval_ptr_dtor_nogc(free_op_data); } } else { zval_ptr_dtor_nogc(object_ptr); @@ -19151,17 +21203,206 @@ assign_dim_convert_to_array: goto try_assign_dim_array; } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) { - goto assign_dim_clean; + goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + 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_UNUSED_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *object_ptr; + zend_free_op free_op_data; + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_UNUSED == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { + dim = NULL; + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_UNUSED, BP_VAR_W); + + } + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + 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)) { + + zval *property_name = NULL; + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_VAR, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_UNUSED == 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);}; + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = NULL; + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = _get_zval_ptr_var_deref((opline+1)->op1.var, execute_data, &free_op_data); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zval_ptr_dtor_nogc(free_op_data); + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; } else { zend_error(E_WARNING, "Cannot use a scalar value as an array"); assign_dim_clean: + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + 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_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *object_ptr; + + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_UNUSED == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { dim = NULL; + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_UNUSED, BP_VAR_W); + + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + 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)) { + + zval *property_name = NULL; + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CV, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_UNUSED == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = NULL; + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, (opline+1)->op1.var); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - FREE_OP(free_op_data1); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -19197,6 +21438,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(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)); + + HANDLE_EXCEPTION(); + } } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -19297,10 +21545,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } } - if (IS_VAR != IS_CONST) { + if (IS_VAR == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -19361,8 +21609,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN if (UNEXPECTED(EG(exception) != NULL)) { if (IS_VAR == IS_CONST) { zval_ptr_dtor_nogc(retval_ptr); - } else { - zval_ptr_dtor_nogc(free_op1); } } #endif @@ -19380,11 +21626,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNU 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, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; @@ -19544,7 +21785,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER( 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_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { + if (IS_VAR & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -19559,12 +21800,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER( } else { zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_VAR == IS_VAR && @@ -19716,13 +21951,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - - HANDLE_EXCEPTION(); - } - do { value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); @@ -19740,7 +21968,7 @@ 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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -19780,12 +22008,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - - HANDLE_EXCEPTION(); - } dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); @@ -19803,22 +22025,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP zend_fetch_dimension_address_RW(&rv, container, dim, IS_CV); value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - var_ptr = Z_INDIRECT(rv); - - if (UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - FREE_OP(free_op_data1); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); - } - - if (UNEXPECTED(var_ptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR(rv))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { + ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); + var_ptr = Z_INDIRECT(rv); ZVAL_DEREF(var_ptr); SEPARATE_ZVAL_NOREF(var_ptr); @@ -19846,13 +22060,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_V value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - - if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -20130,12 +22338,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -20151,7 +22353,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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -20214,12 +22416,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -20234,7 +22430,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP 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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) { @@ -20283,14 +22479,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLE SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var), IS_CV); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -20305,14 +22497,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDL SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var), IS_CV); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -20327,21 +22515,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { + 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->op1.var)); HANDLE_EXCEPTION(); } container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var), IS_CV); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; @@ -20369,15 +22552,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HA SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var), IS_CV); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -20471,16 +22649,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLE HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -20502,15 +22675,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDL HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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_RW); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -20535,21 +22703,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV HANDLE_EXCEPTION(); } - if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { + if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -20575,26 +22738,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HA property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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_UNSET); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 0); + 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_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op1; - zval *object; - zval *property_name; + zval *object, *property_name, *value, tmp; SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); @@ -20606,25 +22763,696 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER } property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + value = EX_CONSTANT((opline+1)->op1); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + } while (0); + } + + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CONST != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CONST == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +exit_assign_obj: + + 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_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op_data; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); HANDLE_EXCEPTION(); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_VAR, property_name, IS_CV, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); + + property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_TMP_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + zval_ptr_dtor_nogc(free_op_data); + } +exit_assign_obj: 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_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op_data; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + + HANDLE_EXCEPTION(); + } + + property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + zval_ptr_dtor_nogc(free_op_data); + } +exit_assign_obj: + + 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_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + + HANDLE_EXCEPTION(); + } + + property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + } while (0); + } + + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CV != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CV == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +exit_assign_obj: + + 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_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op1; zval *object_ptr; - zend_free_op free_op_data1; + zval *value; zval *variable_ptr; zval *dim; @@ -20632,12 +23460,101 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER SAVE_OPLINE(); object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_CV == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CV, BP_VAR_W); - HANDLE_EXCEPTION(); + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + 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)) { + + zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CONST, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_CV == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = EX_CONSTANT((opline+1)->op1); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } } + 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_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *object_ptr; + zend_free_op free_op_data; + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: @@ -20646,7 +23563,7 @@ try_assign_dim_array: 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"); - variable_ptr = &EG(error_zval); + variable_ptr = NULL; } } else { dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); @@ -20654,14 +23571,14 @@ try_assign_dim_array: variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CV, BP_VAR_W); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - FREE_OP(free_op_data1); + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + 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); } @@ -20677,13 +23594,13 @@ try_assign_dim_array: zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_TMP_VAR, (opline+1)->op1, execute_data); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { if (IS_CV == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; HANDLE_EXCEPTION(); } else { @@ -20692,9 +23609,9 @@ try_assign_dim_array: dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); - value = get_zval_ptr_r_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + zval_ptr_dtor_nogc(free_op_data); } } else { zval_ptr_dtor_nogc(object_ptr); @@ -20704,17 +23621,206 @@ assign_dim_convert_to_array: goto try_assign_dim_array; } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) { - goto assign_dim_clean; + goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + 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_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *object_ptr; + zend_free_op free_op_data; + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_CV == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CV, BP_VAR_W); + + } + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + 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)) { + + zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_VAR, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_CV == 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);}; + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = _get_zval_ptr_var_deref((opline+1)->op1.var, execute_data, &free_op_data); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zval_ptr_dtor_nogc(free_op_data); + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; } else { zend_error(E_WARNING, "Cannot use a scalar value as an array"); assign_dim_clean: + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + 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_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *object_ptr; + + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_CV == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CV, BP_VAR_W); + + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + 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)) { + + zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CV, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_CV == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, (opline+1)->op1.var); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - FREE_OP(free_op_data1); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -20725,7 +23831,7 @@ assign_dim_clean: ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op1; @@ -20736,14 +23842,42 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEN value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(0)) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { value = zend_assign_to_variable(variable_ptr, value, IS_CV); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; + /* 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_VAR_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (IS_VAR == 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); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; @@ -20762,53 +23896,49 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER SAVE_OPLINE(); value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op2.var); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets nor overloaded objects"); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && - UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var)))) { + 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"); HANDLE_EXCEPTION(); - } - if (IS_CV == IS_VAR && - (value_ptr == &EG(uninitialized_zval) || - (opline->extended_value == ZEND_RETURNS_FUNCTION && - !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) { - if (!0 && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op2.var)) != IS_INDIRECT)) { /* undo the effect of get_zval_ptr_ptr() */ - Z_TRY_ADDREF_P(value_ptr); - } + + } else if (IS_CV == IS_VAR && + opline->extended_value == ZEND_RETURNS_FUNCTION && + UNEXPECTED(!(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { + zend_error(E_NOTICE, "Only variables should be assigned by reference"); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } - ZEND_VM_TAIL_CALL(ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets nor overloaded objects"); + 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! */ - HANDLE_EXCEPTION(); - } - if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || - (IS_CV == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) { - 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 ((IS_VAR == 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); + } + } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -20837,6 +23967,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(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)); + + HANDLE_EXCEPTION(); + } } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } @@ -20937,10 +24074,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } } - if (IS_VAR != IS_CONST) { + if (IS_VAR == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -20963,11 +24100,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_ 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, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; @@ -21099,11 +24231,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER( HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - - HANDLE_EXCEPTION(); - } offset = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); do { @@ -21195,11 +24322,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER( HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - - HANDLE_EXCEPTION(); - } offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); do { @@ -21251,7 +24373,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND 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_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { + if (IS_VAR & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -21266,12 +24388,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND } else { zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_VAR == IS_VAR && @@ -21387,13 +24503,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } - do { value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); @@ -21411,7 +24520,7 @@ 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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -21451,12 +24560,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); @@ -21474,22 +24577,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP zend_fetch_dimension_address_RW(&rv, container, dim, (IS_TMP_VAR|IS_VAR)); value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - var_ptr = Z_INDIRECT(rv); - - if (UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - zval_ptr_dtor_nogc(free_op2); - FREE_OP(free_op_data1); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); - } - if (UNEXPECTED(var_ptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR(rv))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { + ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); + var_ptr = Z_INDIRECT(rv); ZVAL_DEREF(var_ptr); SEPARATE_ZVAL_NOREF(var_ptr); @@ -21518,13 +24613,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_V value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } - - if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -21803,12 +24892,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } - do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -21824,7 +24907,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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -21888,12 +24971,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } - do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -21908,7 +24985,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP 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(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) { @@ -21958,14 +25035,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HA SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR)); zval_ptr_dtor_nogc(free_op2); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -21980,14 +25053,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_H SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR)); zval_ptr_dtor_nogc(free_op2); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -22002,21 +25071,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TM SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { + 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)); HANDLE_EXCEPTION(); } container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR)); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } zval_ptr_dtor_nogc(free_op2); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; @@ -22044,15 +25108,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVA SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR)); zval_ptr_dtor_nogc(free_op2); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -22147,16 +25206,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HA zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -22178,15 +25232,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_H zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -22211,21 +25260,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TM zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { + if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); zval_ptr_dtor_nogc(free_op2); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -22251,26 +25295,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVA property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } 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), 0); + 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_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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; - zval *property_name; + zval *object, *property_name, *value, tmp; SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); @@ -22282,25 +25320,696 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_HAN } property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + value = EX_CONSTANT((opline+1)->op1); - if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - zval_ptr_dtor_nogc(free_op2); + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CONST != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CONST == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +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_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_VAR, property_name, (IS_TMP_VAR|IS_VAR), (opline+1)->op1_type, (opline+1)->op1, execute_data, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); + + property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_TMP_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + 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_DIM_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } + + property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + 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_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } + + property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CV != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CV == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +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, free_op_data1; + zend_free_op free_op2; zval *value; zval *variable_ptr; zval *dim; @@ -22308,12 +26017,101 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_HAN SAVE_OPLINE(); object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + 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)) { + zend_free_op free_op2; + zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CONST, (opline+1)->op1, execute_data); + zval_ptr_dtor_nogc(free_op2); + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + 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);}; + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + value = EX_CONSTANT((opline+1)->op1); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } } + 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, execute_data, &free_op1); if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: @@ -22322,7 +26120,7 @@ try_assign_dim_array: 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"); - variable_ptr = &EG(error_zval); + variable_ptr = NULL; } } else { dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); @@ -22330,14 +26128,14 @@ try_assign_dim_array: variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_W); zval_ptr_dtor_nogc(free_op2); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - FREE_OP(free_op_data1); + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + 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); } @@ -22353,13 +26151,13 @@ try_assign_dim_array: zend_free_op free_op2; zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_TMP_VAR, (opline+1)->op1, execute_data); zval_ptr_dtor_nogc(free_op2); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; HANDLE_EXCEPTION(); } else { @@ -22368,9 +26166,9 @@ try_assign_dim_array: dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); zval_ptr_dtor_nogc(free_op2); - value = get_zval_ptr_r_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + zval_ptr_dtor_nogc(free_op_data); } } else { zval_ptr_dtor_nogc(object_ptr); @@ -22380,17 +26178,206 @@ assign_dim_convert_to_array: goto try_assign_dim_array; } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) { - goto assign_dim_clean; + goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + 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, execute_data, &free_op1); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + } + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + 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)) { + zend_free_op free_op2; + zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_VAR, (opline+1)->op1, execute_data); + zval_ptr_dtor_nogc(free_op2); + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + 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);}; + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + value = _get_zval_ptr_var_deref((opline+1)->op1.var, execute_data, &free_op_data); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zval_ptr_dtor_nogc(free_op_data); + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; } else { zend_error(E_WARNING, "Cannot use a scalar value as an array"); assign_dim_clean: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + 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, execute_data, &free_op1); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + 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)) { + zend_free_op free_op2; + zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CV, (opline+1)->op1, execute_data); zval_ptr_dtor_nogc(free_op2); - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - FREE_OP(free_op_data1); + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + 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);}; + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, (opline+1)->op1.var); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -22426,6 +26413,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(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)); } @@ -22526,10 +26520,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V } } - if (IS_VAR != IS_CONST) { + if (IS_VAR == IS_UNUSED) { /* previous opcode is ZEND_FETCH_CLASS */ - if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { + if ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -22552,11 +26546,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP 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, execute_data, &free_op1); - if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; @@ -22688,11 +26677,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HAND zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); do { @@ -22785,11 +26769,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HAND zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); do { @@ -22815,6 +26794,67 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HAND ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *result; + zend_function *constructor; + zend_class_entry *ce; + zend_execute_data *call; + + 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_VM_NEXT_OPCODE_CHECK_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)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + + result = EX_VAR(opline->result.var); + if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { + HANDLE_EXCEPTION(); + } + + constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); + if (constructor == NULL) { + /* 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); + } + + /* 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 { + /* 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); + } + + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -22854,19 +26894,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND } while (0); ce = Z_OBJCE_P(obj); - clone = ce ? ce->clone : NULL; - clone_call = Z_OBJ_HT_P(obj)->clone_obj; + clone = ce->clone; + clone_call = Z_OBJ_HT_P(obj)->clone_obj; if (UNEXPECTED(clone_call == NULL)) { - if (ce) { - zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); - } else { - zend_throw_error(NULL, "Trying to clone an uncloneable object"); - } + zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); HANDLE_EXCEPTION(); } - if (ce && clone) { + 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. */ @@ -22886,11 +26922,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND } } - if (EXPECTED(EG(exception) == NULL)) { - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); - if (UNEXPECTED(!RETURN_VALUE_USED(opline)) || UNEXPECTED(EG(exception) != NULL)) { - OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); - } + ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); + if (UNEXPECTED(EG(exception) != NULL)) { + OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -22946,13 +26980,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP property = EX_CONSTANT(opline->op2); - if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - - HANDLE_EXCEPTION(); - } - do { value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); @@ -22970,7 +26997,7 @@ 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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -23010,12 +27037,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - - HANDLE_EXCEPTION(); - } dim = EX_CONSTANT(opline->op2); @@ -23033,22 +27054,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP zend_fetch_dimension_address_RW(&rv, container, dim, IS_CONST); value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - var_ptr = Z_INDIRECT(rv); - - if (UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - - FREE_OP(free_op_data1); - HANDLE_EXCEPTION(); - } - - if (UNEXPECTED(var_ptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR(rv))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { + ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); + var_ptr = Z_INDIRECT(rv); ZVAL_DEREF(var_ptr); SEPARATE_ZVAL_NOREF(var_ptr); @@ -23324,12 +27337,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE property = EX_CONSTANT(opline->op2); - if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -23345,7 +27352,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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -23408,12 +27415,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP property = EX_CONSTANT(opline->op2); - if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -23428,7 +27429,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP 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(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) { @@ -23556,16 +27557,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_ HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -23587,15 +27583,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -23692,21 +27683,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) { + if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -23732,26 +27718,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CO property = EX_CONSTANT(opline->op2); - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + 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_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 - zval *object; - zval *property_name; + zval *object, *property_name, *value, tmp; SAVE_OPLINE(); object = _get_obj_zval_ptr_unused(execute_data); @@ -23763,13 +27743,684 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_H } property_name = EX_CONSTANT(opline->op2); + value = EX_CONSTANT((opline+1)->op1); + + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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)); + } - if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); + OBJ_RELEASE(obj); + goto exit_assign_obj; + } + Z_DELREF_P(object); + } else { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + } while (0); + } + + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CONST != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CONST == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +exit_assign_obj: + + + /* 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) +{ + USE_OPLINE + zend_free_op free_op_data; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_obj_zval_ptr_unused(execute_data); + + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + + HANDLE_EXCEPTION(); + } + + property_name = EX_CONSTANT(opline->op2); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_TMP_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + zval_ptr_dtor_nogc(free_op_data); + } +exit_assign_obj: + + + /* 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) +{ + USE_OPLINE + zend_free_op free_op_data; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_obj_zval_ptr_unused(execute_data); + + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); HANDLE_EXCEPTION(); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_UNUSED, property_name, IS_CONST, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); + + property_name = EX_CONSTANT(opline->op2); + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + zval_ptr_dtor_nogc(free_op_data); + } +exit_assign_obj: + + + /* 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) +{ + USE_OPLINE + + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_obj_zval_ptr_unused(execute_data); + + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + + HANDLE_EXCEPTION(); + } + + property_name = EX_CONSTANT(opline->op2); + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + } while (0); + } + + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CV != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CV == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +exit_assign_obj: /* assign_obj has two opcodes! */ @@ -23928,110 +28579,277 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_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; + zend_class_entry *ce; + zend_object *object; + zend_function *fbc; + zend_execute_data *call; SAVE_OPLINE(); - if (IS_UNUSED == IS_UNUSED) { - 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 ((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)))); + + 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)) { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } - /* non-qualified constant - allow text substitution */ - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", - 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, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); 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)); + + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + + if (IS_UNUSED == IS_CONST && + IS_CONST == 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_CONST == IS_CONST && + (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce))) { + /* do nothing */ + } else if (IS_CONST != IS_UNUSED) { + + + function_name = EX_CONSTANT(opline->op2); + if (IS_CONST != IS_CONST) { + if (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(); + } + } + zend_throw_error(NULL, "Function name must be a string"); + + HANDLE_EXCEPTION(); + } while (0); + } + } + + if (ce->get_static_method) { + fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL)); } -#ifdef ZTS - if (c->flags & CONST_PERSISTENT) { - ZVAL_DUP(EX_VAR(opline->result.var), &c->value); + 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)); + } + + 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)))) { + 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 (IS_CONST != IS_CONST) { + + } + } else { + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); + } + if (Z_OBJ(EX(This)) && 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; + } + + object = NULL; + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_OBJ(EX(This)) && instanceof_function(Z_OBJCE(EX(This)), ce)) { + object = Z_OBJ(EX(This)); + ce = object->ce; } else { - ZVAL_COPY(EX_VAR(opline->result.var), &c->value); + 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(); + } } -#else + } + + 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) { + ce = EX(called_scope); + } + } + + 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_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_constant *c; + + SAVE_OPLINE(); + + 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 ((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_NOTICE, "Use of undefined constant %s - assumed '%s'", + 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))); + 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 - } else { - /* class constant */ - zend_class_entry *ce; - zval *value; - 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))); - ZVAL_DEREF(value); + 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; + 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))); + 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)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); - } - HANDLE_EXCEPTION(); + 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)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce); + 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)); + HANDLE_EXCEPTION(); } } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); - if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { - ZVAL_DEREF(value); - break; - } } + if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) { + break; + } + } - if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { - ZVAL_DEREF(value); - if (Z_CONSTANT_P(value)) { - EG(scope) = ce; - zval_update_constant_ex(value, 1, NULL); - EG(scope) = EX(func)->op_array.scope; - if (UNEXPECTED(EG(exception) != NULL)) { - 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); + if (EXPECTED((c = zend_hash_find_ptr(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) { + if (!zend_verify_const_access(c, EG(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))); + HANDLE_EXCEPTION(); + } + value = &c->value; + if (Z_CONSTANT_P(value)) { + EG(scope) = ce; + zval_update_constant_ex(value, 1, NULL); + EG(scope) = EX(func)->op_array.scope; + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } + } + if (IS_UNUSED == IS_CONST) { + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value); } else { - zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value); } - } 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); + zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + HANDLE_EXCEPTION(); } -#else + } 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); -#endif } +#else + ZVAL_COPY(EX_VAR(opline->result.var), value); +#endif + ZEND_VM_NEXT_OPCODE(); } @@ -24082,11 +28900,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HA HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - - HANDLE_EXCEPTION(); - } offset = EX_CONSTANT(opline->op2); do { @@ -24178,11 +28991,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HA HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - - HANDLE_EXCEPTION(); - } offset = EX_CONSTANT(opline->op2); do { @@ -24310,6 +29118,9 @@ num_index_prop: 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; @@ -24417,7 +29228,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE 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_UNUSED == IS_TMP_VAR) { + if (IS_UNUSED & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -24432,12 +29243,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE } else { zval *value_ptr = NULL; - if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_UNUSED == IS_VAR && @@ -24558,7 +29363,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER( 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_UNUSED == IS_TMP_VAR) { + if (IS_UNUSED & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -24573,12 +29378,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER( } else { zval *value_ptr = NULL; - if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_UNUSED == IS_VAR && @@ -24699,7 +29498,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER( 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_UNUSED == IS_TMP_VAR) { + if (IS_UNUSED & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -24714,12 +29513,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER( } else { zval *value_ptr = NULL; - if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_UNUSED == IS_VAR && @@ -24828,12 +29621,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - - HANDLE_EXCEPTION(); - } dim = NULL; @@ -24851,22 +29638,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP zend_fetch_dimension_address_RW(&rv, container, dim, IS_UNUSED); value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - var_ptr = Z_INDIRECT(rv); - - if (UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - FREE_OP(free_op_data1); - - HANDLE_EXCEPTION(); - } - - if (UNEXPECTED(var_ptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR(rv))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { + ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); + var_ptr = Z_INDIRECT(rv); ZVAL_DEREF(var_ptr); SEPARATE_ZVAL_NOREF(var_ptr); @@ -25123,6 +29902,154 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_UNUSED_UNUSED_ #endif } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_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)) { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); + 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)); + + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + + if (IS_UNUSED == IS_CONST && + IS_UNUSED == 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_UNUSED == IS_CONST && + (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce))) { + /* do nothing */ + } else if (IS_UNUSED != IS_UNUSED) { + + + function_name = NULL; + if (IS_UNUSED != IS_CONST) { + if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if (IS_UNUSED & (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_UNUSED == 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"); + + 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_UNUSED == 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)); + } + + HANDLE_EXCEPTION(); + } + if (IS_UNUSED == 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 (IS_UNUSED != IS_CONST) { + + } + } else { + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); + } + if (Z_OBJ(EX(This)) && 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; + } + + object = NULL; + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_OBJ(EX(This)) && 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) { + ce = EX(called_scope); + } + } + + 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_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -25171,8 +30098,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED if (UNEXPECTED(EG(exception) != NULL)) { if (IS_UNUSED == IS_CONST) { zval_ptr_dtor_nogc(retval_ptr); - } else { - } } #endif @@ -25238,7 +30163,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL 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_UNUSED == IS_TMP_VAR) { + if (IS_UNUSED & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -25253,12 +30178,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL } else { zval *value_ptr = NULL; - if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_UNUSED == IS_VAR && @@ -25373,13 +30292,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - - HANDLE_EXCEPTION(); - } - do { value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); @@ -25397,7 +30309,7 @@ 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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -25437,12 +30349,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - - HANDLE_EXCEPTION(); - } dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); @@ -25460,22 +30366,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP zend_fetch_dimension_address_RW(&rv, container, dim, IS_CV); value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - var_ptr = Z_INDIRECT(rv); - - if (UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - - FREE_OP(free_op_data1); - HANDLE_EXCEPTION(); - } - - if (UNEXPECTED(var_ptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR(rv))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { + ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); + var_ptr = Z_INDIRECT(rv); ZVAL_DEREF(var_ptr); SEPARATE_ZVAL_NOREF(var_ptr); @@ -25751,12 +30649,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -25772,7 +30664,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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -25835,12 +30727,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -25855,7 +30741,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP 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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) { @@ -25983,16 +30869,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HAN HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -26014,15 +30895,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HA HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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_RW); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -26119,21 +30995,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) { + if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -26159,26 +31030,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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_UNSET); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 0); + 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_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property_name; + zval *object, *property_name, *value, tmp; SAVE_OPLINE(); object = _get_obj_zval_ptr_unused(execute_data); @@ -26190,13 +31055,684 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HAND } property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + value = EX_CONSTANT((opline+1)->op1); - if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + } while (0); + } + + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CONST != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CONST == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +exit_assign_obj: + + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op_data; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_obj_zval_ptr_unused(execute_data); + + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); HANDLE_EXCEPTION(); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_UNUSED, property_name, IS_CV, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); + + property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_TMP_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + zval_ptr_dtor_nogc(free_op_data); + } +exit_assign_obj: + + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op_data; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_obj_zval_ptr_unused(execute_data); + + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + + HANDLE_EXCEPTION(); + } + + property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + zval_ptr_dtor_nogc(free_op_data); + } +exit_assign_obj: + + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_obj_zval_ptr_unused(execute_data); + + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + + HANDLE_EXCEPTION(); + } + + property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + } while (0); + } + + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CV != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CV == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +exit_assign_obj: /* assign_obj has two opcodes! */ @@ -26355,6 +31891,154 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_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)) { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); + 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)); + + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + + if (IS_UNUSED == IS_CONST && + IS_CV == 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_CV == IS_CONST && + (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce))) { + /* do nothing */ + } else if (IS_CV != IS_UNUSED) { + + + function_name = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); + if (IS_CV != IS_CONST) { + if (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)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Function name must be a string"); + + 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_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(ce->name), Z_STRVAL_P(function_name)); + } + + 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)))) { + 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 (IS_CV != IS_CONST) { + + } + } else { + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); + } + if (Z_OBJ(EX(This)) && 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; + } + + object = NULL; + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_OBJ(EX(This)) && 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) { + ce = EX(called_scope); + } + } + + 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_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *array; @@ -26402,11 +32086,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDL HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - - HANDLE_EXCEPTION(); - } offset = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); do { @@ -26498,11 +32177,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDL HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - - HANDLE_EXCEPTION(); - } offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); do { @@ -26630,6 +32304,9 @@ num_index_prop: 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; @@ -26737,7 +32414,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z 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_UNUSED == IS_TMP_VAR) { + if (IS_UNUSED & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -26752,12 +32429,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z } else { zval *value_ptr = NULL; - if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_UNUSED == IS_VAR && @@ -26872,13 +32543,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } - do { value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); @@ -26896,7 +32560,7 @@ 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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -26936,12 +32600,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); @@ -26959,22 +32617,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP zend_fetch_dimension_address_RW(&rv, container, dim, (IS_TMP_VAR|IS_VAR)); value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - var_ptr = Z_INDIRECT(rv); - - if (UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - zval_ptr_dtor_nogc(free_op2); - FREE_OP(free_op_data1); - HANDLE_EXCEPTION(); - } - - if (UNEXPECTED(var_ptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR(rv))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { + ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); + var_ptr = Z_INDIRECT(rv); ZVAL_DEREF(var_ptr); SEPARATE_ZVAL_NOREF(var_ptr); @@ -27251,12 +32901,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } - do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -27272,7 +32916,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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -27336,12 +32980,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } - do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -27356,7 +32994,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP 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(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) { @@ -27486,16 +33124,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -27517,15 +33150,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVA zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -27623,21 +33251,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) { + if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -27663,26 +33286,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TM property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } 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), 0); + 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_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; - zval *property_name; + zval *object, *property_name, *value, tmp; SAVE_OPLINE(); object = _get_obj_zval_ptr_unused(execute_data); @@ -27694,13 +33311,684 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + value = EX_CONSTANT((opline+1)->op1); - if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - zval_ptr_dtor_nogc(free_op2); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CONST != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CONST == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +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_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_obj_zval_ptr_unused(execute_data); + + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } + + property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_TMP_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + 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_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_obj_zval_ptr_unused(execute_data); + + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_UNUSED, property_name, (IS_TMP_VAR|IS_VAR), (opline+1)->op1_type, (opline+1)->op1, execute_data, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); + + property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + 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_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_obj_zval_ptr_unused(execute_data); + + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } + + property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CV != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CV == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +exit_assign_obj: zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ @@ -27860,6 +34148,154 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +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)) { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1))); + 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 && + (fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce))) { + /* do nothing */ + } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + zend_free_op free_op2; + + function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + 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 ((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_OBJ(EX(This)) && 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; + } + + object = NULL; + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_OBJ(EX(This)) && 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) { + ce = EX(called_scope); + } + } + + 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_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *array; @@ -27907,11 +34343,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_TMPVAR_H zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); do { @@ -28004,11 +34435,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_H zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); do { @@ -28137,6 +34563,9 @@ num_index_prop: 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; @@ -28241,7 +34670,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_ 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 (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + if (IS_CV == 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(); @@ -28255,7 +34684,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_ ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -28263,22 +34692,55 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_O var_ptr = _get_zval_ptr_cv_undef_BP_VAR_RW(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - HANDLE_EXCEPTION(); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_increment_function(var_ptr); + if (UNEXPECTED(0)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); } + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { + if (UNEXPECTED(0)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { + var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); + } + ZVAL_DEREF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); + + increment_function(var_ptr); + + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *var_ptr; + + var_ptr = _get_zval_ptr_cv_undef_BP_VAR_RW(execute_data, opline->op1.var); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { fast_long_increment_function(var_ptr); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(1)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); } ZEND_VM_NEXT_OPCODE(); } - if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { + if (UNEXPECTED(1)) { ZVAL_NULL(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE(); @@ -28293,14 +34755,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_O increment_function(var_ptr); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(1)) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -28308,22 +34770,55 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_O var_ptr = _get_zval_ptr_cv_undef_BP_VAR_RW(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - HANDLE_EXCEPTION(); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_decrement_function(var_ptr); + if (UNEXPECTED(0)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); + } + + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { + if (UNEXPECTED(0)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + ZEND_VM_NEXT_OPCODE(); } + SAVE_OPLINE(); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { + var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW); + } + ZVAL_DEREF(var_ptr); + SEPARATE_ZVAL_NOREF(var_ptr); + + decrement_function(var_ptr); + + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *var_ptr; + + var_ptr = _get_zval_ptr_cv_undef_BP_VAR_RW(execute_data, opline->op1.var); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { fast_long_decrement_function(var_ptr); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(1)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); } ZEND_VM_NEXT_OPCODE(); } - if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { + if (UNEXPECTED(1)) { ZVAL_NULL(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE(); @@ -28338,7 +34833,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_O decrement_function(var_ptr); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(1)) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } @@ -28353,19 +34848,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_ var_ptr = _get_zval_ptr_cv_undef_BP_VAR_RW(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - HANDLE_EXCEPTION(); - } - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); fast_long_increment_function(var_ptr); ZEND_VM_NEXT_OPCODE(); } - if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); ZEND_VM_NEXT_OPCODE(); } @@ -28391,19 +34880,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_ var_ptr = _get_zval_ptr_cv_undef_BP_VAR_RW(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - HANDLE_EXCEPTION(); - } - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); fast_long_decrement_function(var_ptr); ZEND_VM_NEXT_OPCODE(); } - if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); ZEND_VM_NEXT_OPCODE(); } @@ -28653,14 +35136,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OP ZVAL_NULL(EX(return_value)); } } else if (!EX(return_value)) { - if (IS_CV == IS_VAR || IS_CV == IS_TMP_VAR ) { + if (IS_CV & (IS_VAR|IS_TMP_VAR)) { if (Z_REFCOUNTED_P(free_op1) && !Z_DELREF_P(free_op1)) { SAVE_OPLINE(); zval_dtor_func_for_ptr(Z_COUNTED_P(free_op1)); } } } else { - if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); if (IS_CV == IS_CONST) { if (UNEXPECTED(Z_OPT_COPYABLE_P(EX(return_value)))) { @@ -28698,7 +35181,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER( SAVE_OPLINE(); do { - if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR || + if ((IS_CV & (IS_CONST|IS_TMP_VAR)) || (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { /* Not supposed to happen, but we'll allow it */ zend_error(E_NOTICE, "Only variable references should be returned by reference"); @@ -28720,11 +35203,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER( retval_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(retval_ptr == NULL)) { - zend_throw_error(NULL, "Cannot return string offsets by reference"); - HANDLE_EXCEPTION(); - } - if (IS_CV == IS_VAR) { if (retval_ptr == &EG(uninitialized_zval) || (opline->extended_value == ZEND_RETURNS_FUNCTION && @@ -28762,7 +35240,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_CV_HANDL retval = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); /* Copy return value into generator->retval */ - if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { ZVAL_COPY_VALUE(&generator->retval, retval); if (IS_CV == IS_CONST) { if (UNEXPECTED(Z_OPT_COPYABLE(generator->retval))) { @@ -28883,15 +35361,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_ SAVE_OPLINE(); varptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(varptr == NULL)) { - zend_throw_error(NULL, "Only variables can be passed by reference"); - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - ZVAL_UNDEF(arg); - HANDLE_EXCEPTION(); - } - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - if (IS_CV == IS_VAR && UNEXPECTED(varptr == &EG(error_zval))) { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(varptr))) { ZVAL_NEW_REF(arg, &EG(uninitialized_zval)); ZEND_VM_NEXT_OPCODE(); } @@ -28915,7 +35386,56 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_CV_HANDLER(ZE uint32_t arg_num = opline->op2.num; - if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { + if (EXPECTED(0)) { + if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_var_by_ref; + } + } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { +send_var_by_ref: + ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + varptr = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { + SAVE_OPLINE(); + GET_OP1_UNDEF_CV(varptr, BP_VAR_R); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + ZVAL_NULL(arg); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + + if (IS_CV == IS_CV) { + ZVAL_OPT_DEREF(varptr); + ZVAL_COPY(arg, varptr); + } else /* if (IS_CV == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); + + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); + } + } else { + ZVAL_COPY_VALUE(arg, varptr); + } + } + + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_CV_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varptr, *arg; + + uint32_t arg_num = opline->op2.num; + + if (EXPECTED(1)) { if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { goto send_var_by_ref; } @@ -29021,7 +35541,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCO 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 (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + if (IS_CV == 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(); @@ -29074,19 +35594,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC } while (0); ce = Z_OBJCE_P(obj); - clone = ce ? ce->clone : NULL; - clone_call = Z_OBJ_HT_P(obj)->clone_obj; + clone = ce->clone; + clone_call = Z_OBJ_HT_P(obj)->clone_obj; if (UNEXPECTED(clone_call == NULL)) { - if (ce) { - zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); - } else { - zend_throw_error(NULL, "Trying to clone an uncloneable object"); - } + zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); HANDLE_EXCEPTION(); } - if (ce && clone) { + 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. */ @@ -29106,11 +35622,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC } } - if (EXPECTED(EG(exception) == NULL)) { - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); - if (UNEXPECTED(!RETURN_VALUE_USED(opline)) || UNEXPECTED(EG(exception) != NULL)) { - OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); - } + ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); + if (UNEXPECTED(EG(exception) != NULL)) { + OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -29896,7 +36410,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CV_HANDLER(ZEN if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { zend_class_entry *ce = Z_OBJCE_P(value); - if (UNEXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) || + if (EXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) || EXPECTED(memcmp(ZSTR_VAL(ce->name), "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) { result = 1; } @@ -30577,13 +37091,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP property = EX_CONSTANT(opline->op2); - if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - - HANDLE_EXCEPTION(); - } - do { value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); @@ -30601,7 +37108,7 @@ 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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -30641,12 +37148,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - - HANDLE_EXCEPTION(); - } dim = EX_CONSTANT(opline->op2); @@ -30664,22 +37165,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP zend_fetch_dimension_address_RW(&rv, container, dim, IS_CONST); value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - var_ptr = Z_INDIRECT(rv); - - if (UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - - FREE_OP(free_op_data1); - HANDLE_EXCEPTION(); - } - - if (UNEXPECTED(var_ptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR(rv))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { + ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); + var_ptr = Z_INDIRECT(rv); ZVAL_DEREF(var_ptr); SEPARATE_ZVAL_NOREF(var_ptr); @@ -30707,13 +37200,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_C value = EX_CONSTANT(opline->op2); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - - if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -30991,12 +37478,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE property = EX_CONSTANT(opline->op2); - if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -31012,7 +37493,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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -31075,12 +37556,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP property = EX_CONSTANT(opline->op2); - if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -31095,7 +37570,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP 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(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) { @@ -31135,14 +37610,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_CV_CONST_HAN ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_CV_CONST(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type ZEND_OPCODE_HANDLER_ARGS_DC) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_CV_CONST(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE zval *varname; zval *retval; zend_string *name; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); varname = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); @@ -31159,119 +37634,73 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = 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)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } + if (IS_CONST == IS_CONST) { + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto fetch_var_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)) { - if (IS_CV != IS_CONST) { - zend_string_release(name); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CV == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - HANDLE_EXCEPTION(); + goto fetch_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)) { + if (IS_CV != IS_CONST) { + zend_string_release(name); } - goto fetch_var_return; - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - if (IS_CV != IS_CONST) { - zend_string_release(name); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - - HANDLE_EXCEPTION(); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - if (IS_CV == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); - } - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { - 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) { - 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 (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) { + zend_string_release(name); } + + HANDLE_EXCEPTION(); } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + if (IS_CV == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - HANDLE_EXCEPTION(); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + goto fetch_static_prop_return; } } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + if (IS_CV != IS_CONST) { + zend_string_release(name); + } + + HANDLE_EXCEPTION(); + } + if (IS_CV == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } if (IS_CV != IS_CONST) { zend_string_release(name); } -fetch_var_return: +fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -31284,40 +37713,40 @@ fetch_var_return: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_CONST(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CV_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_var_address_helper_SPEC_CV_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_CONST(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_CONST(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -31343,14 +37772,10 @@ 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(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -31365,14 +37790,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HAN SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -31401,21 +37822,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CON SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); HANDLE_EXCEPTION(); } container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -31443,15 +37859,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_ SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, EX_CONSTANT(opline->op2), IS_CONST); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -31545,16 +37956,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HAND HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -31576,15 +37982,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HAN HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -31681,21 +38082,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CON HANDLE_EXCEPTION(); } - if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -31721,15 +38117,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_ property = EX_CONSTANT(opline->op2); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -31739,26 +38130,76 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_CONST_HANDL { USE_OPLINE + zval *container; + zval *offset = EX_CONSTANT(opline->op2); SAVE_OPLINE(); container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); try_fetch_list: if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - zval *value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2))); + zval *value; + zend_string *str; + zend_ulong hval; - if (UNEXPECTED(value == NULL)) { - zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2))); - ZVAL_NULL(EX_VAR(opline->result.var)); +assign_again_list: + if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_list: + value = zend_hash_index_find(Z_ARRVAL_P(container), hval); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_list; + } + +str_index_list: + value = zend_hash_find(Z_ARRVAL_P(container), str); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str)); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (UNEXPECTED(str != Z_STR_P(offset))) { + zend_string_release(str); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto assign_again_list; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index_list; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset)); + hval = Z_RES_HANDLE_P(offset); } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); + zend_error(E_WARNING, "Illegal offset type"); } } else if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) && EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) { zval *result = EX_VAR(opline->result.var); - zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, EX_CONSTANT(opline->op2), BP_VAR_R, result); + zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result); if (retval) { if (result != retval) { @@ -31776,15 +38217,15 @@ try_fetch_list: } ZVAL_NULL(EX_VAR(opline->result.var)); } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property_name; + zval *object, *property_name, *value, tmp; SAVE_OPLINE(); object = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); @@ -31796,25 +38237,696 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDL } property_name = EX_CONSTANT(opline->op2); + value = EX_CONSTANT((opline+1)->op1); + + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + } while (0); + } + + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CONST != IS_TMP_VAR) { + ZVAL_DEREF(value); + } - if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CONST == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +exit_assign_obj: + + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op_data; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); HANDLE_EXCEPTION(); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_CV, property_name, IS_CONST, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); + + property_name = EX_CONSTANT(opline->op2); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_TMP_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + zval_ptr_dtor_nogc(free_op_data); + } +exit_assign_obj: /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op_data; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + + HANDLE_EXCEPTION(); + } + + property_name = EX_CONSTANT(opline->op2); + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + zval_ptr_dtor_nogc(free_op_data); + } +exit_assign_obj: + + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + + HANDLE_EXCEPTION(); + } + + property_name = EX_CONSTANT(opline->op2); + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + } while (0); + } + + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CV != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CV == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +exit_assign_obj: + + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr; - zend_free_op free_op_data1; + zval *value; zval *variable_ptr; zval *dim; @@ -31822,13 +38934,102 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDL SAVE_OPLINE(); object_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_CONST == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { + dim = EX_CONSTANT(opline->op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CONST, BP_VAR_W); - HANDLE_EXCEPTION(); + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + 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)) { + + zval *property_name = EX_CONSTANT(opline->op2); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CONST, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_CONST == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = EX_CONSTANT(opline->op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = EX_CONSTANT((opline+1)->op1); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } } + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_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(execute_data, opline->op1.var); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: if (IS_CONST == IS_UNUSED) { @@ -31836,7 +39037,7 @@ try_assign_dim_array: 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"); - variable_ptr = &EG(error_zval); + variable_ptr = NULL; } } else { dim = EX_CONSTANT(opline->op2); @@ -31844,14 +39045,14 @@ try_assign_dim_array: variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CONST, BP_VAR_W); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - FREE_OP(free_op_data1); + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + 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); } @@ -31867,13 +39068,13 @@ try_assign_dim_array: zval *property_name = EX_CONSTANT(opline->op2); - zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_TMP_VAR, (opline+1)->op1, execute_data); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { if (IS_CONST == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); HANDLE_EXCEPTION(); } else { @@ -31882,9 +39083,9 @@ try_assign_dim_array: dim = EX_CONSTANT(opline->op2); offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); - value = get_zval_ptr_r_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + zval_ptr_dtor_nogc(free_op_data); } } else { zval_ptr_dtor_nogc(object_ptr); @@ -31894,17 +39095,206 @@ assign_dim_convert_to_array: goto try_assign_dim_array; } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) { - goto assign_dim_clean; + goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_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(execute_data, opline->op1.var); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_CONST == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; } + } else { + dim = EX_CONSTANT(opline->op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CONST, BP_VAR_W); + + } + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + 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)) { + + zval *property_name = EX_CONSTANT(opline->op2); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_VAR, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_CONST == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = EX_CONSTANT(opline->op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = _get_zval_ptr_var_deref((opline+1)->op1.var, execute_data, &free_op_data); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zval_ptr_dtor_nogc(free_op_data); + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; } else { zend_error(E_WARNING, "Cannot use a scalar value as an array"); assign_dim_clean: + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_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(execute_data, opline->op1.var); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_CONST == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { dim = EX_CONSTANT(opline->op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CONST, BP_VAR_W); + + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + 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)) { + + zval *property_name = EX_CONSTANT(opline->op2); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CV, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_CONST == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = EX_CONSTANT(opline->op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, (opline+1)->op1.var); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - FREE_OP(free_op_data1); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -31915,7 +39305,7 @@ assign_dim_clean: ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -31926,14 +39316,42 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(Z value = EX_CONSTANT(opline->op2); variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(0)) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { value = zend_assign_to_variable(variable_ptr, value, IS_CONST); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + 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_CONST_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + value = EX_CONSTANT(opline->op2); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + 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_CONST); + if (UNEXPECTED(1)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -32213,11 +39631,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONS 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(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); @@ -32333,40 +39746,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDL } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval tmp, *varname; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); - if (IS_CV == IS_CV && - IS_CONST == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - zval *var = EX_VAR(opline->op1.var); - - if (Z_REFCOUNTED_P(var)) { - zend_refcounted *garbage = Z_COUNTED_P(var); - - if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); - zval_dtor_func_for_ptr(garbage); - } else { - zval *z = var; - ZVAL_DEREF(z); - if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) { - ZVAL_UNDEF(var); - gc_possible_root(Z_COUNTED_P(z)); - } else { - ZVAL_UNDEF(var); - } - } - } else { - ZVAL_UNDEF(var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } varname = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); @@ -32379,33 +39766,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLE varname = &tmp; } - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + 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)) { - 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)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - HANDLE_EXCEPTION(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + 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)); + 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_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } + + HANDLE_EXCEPTION(); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + 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)); @@ -32430,11 +39820,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLE HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - - HANDLE_EXCEPTION(); - } offset = EX_CONSTANT(opline->op2); do { @@ -32526,11 +39911,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLE HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - - HANDLE_EXCEPTION(); - } offset = EX_CONSTANT(opline->op2); do { @@ -32555,103 +39935,87 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *value; int result; - if (IS_CV == IS_CV && - IS_CONST == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - 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))) { - 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(); - } else { - - zval tmp, *varname; - - SAVE_OPLINE(); - varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); - 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_CONST != IS_UNUSED) { - zend_class_entry *ce; - - 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*)); - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + zval tmp, *varname; + zend_class_entry *ce; - goto is_var_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_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CV == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + SAVE_OPLINE(); + varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); + ZVAL_UNDEF(&tmp); + if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + 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*)); - goto is_var_return; - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; } - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + 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_VM_NEXT_OPCODE_CHECK_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_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } - if (IS_CV == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + HANDLE_EXCEPTION(); } } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + if (IS_CV == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } -is_var_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); + goto is_static_prop_return; } + } - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + 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_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -32757,6 +40121,9 @@ num_index_prop: 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; @@ -32862,6 +40229,13 @@ try_instanceof: } 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)); + + HANDLE_EXCEPTION(); + } } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } @@ -32908,7 +40282,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE 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_CV == IS_TMP_VAR) { + if (IS_CV & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -32923,12 +40297,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE } else { zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_CV == IS_VAR && @@ -33113,6 +40481,57 @@ check_indirect: ZEND_VM_NEXT_OPCODE(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + HashTable *ht; + zval *varname; + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + zval_ptr_dtor(variable_ptr); + + ht = EX(func)->op_array.static_variables; + ZEND_ASSERT(ht != NULL); + if (GC_REFCOUNT(ht) > 1) { + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_REFCOUNT(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)); + + if (opline->extended_value) { + if (Z_CONSTANT_P(value)) { + if (UNEXPECTED(zval_update_constant_ex(value, 1, NULL) != SUCCESS)) { + ZVAL_NULL(variable_ptr); + HANDLE_EXCEPTION(); + } + } + if (UNEXPECTED(!Z_ISREF_P(value))) { + zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference)); + GC_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; + ZVAL_REF(variable_ptr, ref); + } else { + Z_ADDREF_P(value); + ZVAL_REF(variable_ptr, Z_REF_P(value)); + } + } else { + ZVAL_COPY(variable_ptr, value); + } + + 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 @@ -33149,7 +40568,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_H ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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; @@ -33160,14 +40579,42 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEN value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(0)) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + 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, execute_data, &free_op2); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + 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); } @@ -33204,7 +40651,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND 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_CV == IS_TMP_VAR) { + if (IS_CV & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -33219,12 +40666,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND } else { zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_CV == IS_VAR && @@ -33354,14 +40795,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_H ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) +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; zend_string *name; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); varname = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); @@ -33378,119 +40819,73 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = 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)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } + if (IS_VAR == IS_CONST) { + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto fetch_var_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)) { - if (IS_CV != IS_CONST) { - zend_string_release(name); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CV == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); + goto fetch_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)) { + if (IS_CV != IS_CONST) { + zend_string_release(name); } - goto fetch_var_return; - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - if (IS_CV != IS_CONST) { - zend_string_release(name); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - - HANDLE_EXCEPTION(); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - if (IS_CV == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); - } - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { - 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) { - 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 (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_string_release(name); } + + HANDLE_EXCEPTION(); } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + if (IS_CV == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - HANDLE_EXCEPTION(); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + goto fetch_static_prop_return; } } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + if (IS_CV != IS_CONST) { + zend_string_release(name); + } + + HANDLE_EXCEPTION(); + } + if (IS_CV == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } if (IS_CV != IS_CONST) { zend_string_release(name); } -fetch_var_return: +fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -33503,43 +40898,43 @@ fetch_var_return: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_CV_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_CV_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_CV_VAR(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_CV_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_var_address_helper_SPEC_CV_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_CV_VAR(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_CV_VAR(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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; @@ -33550,14 +40945,42 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEN value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { zval_ptr_dtor_nogc(free_op2); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(0)) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { value = zend_assign_to_variable(variable_ptr, value, IS_VAR); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + 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, execute_data, &free_op2); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + 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); } @@ -33576,90 +40999,60 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER SAVE_OPLINE(); value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets nor overloaded objects"); - - HANDLE_EXCEPTION(); - } 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_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);}; HANDLE_EXCEPTION(); - } - if (IS_VAR == IS_VAR && - (value_ptr == &EG(uninitialized_zval) || - (opline->extended_value == ZEND_RETURNS_FUNCTION && - !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) { - if (!(free_op2 != NULL) && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op2.var)) != IS_INDIRECT)) { /* undo the effect of get_zval_ptr_ptr() */ - Z_TRY_ADDREF_P(value_ptr); - } + + } else if (IS_VAR == IS_VAR && + opline->extended_value == ZEND_RETURNS_FUNCTION && + UNEXPECTED(!(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { + 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);}; HANDLE_EXCEPTION(); } - ZEND_VM_TAIL_CALL(ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets nor overloaded objects"); - if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);}; - HANDLE_EXCEPTION(); - } - if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || - (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) { - variable_ptr = &EG(uninitialized_zval); + 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 { - 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 ((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(free_op2)) {zval_ptr_dtor_nogc(free_op2);}; + 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_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval tmp, *varname; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); - if (IS_CV == IS_CV && - IS_VAR == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - zval *var = EX_VAR(opline->op1.var); - - if (Z_REFCOUNTED_P(var)) { - zend_refcounted *garbage = Z_COUNTED_P(var); - - if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); - zval_dtor_func_for_ptr(garbage); - } else { - zval *z = var; - ZVAL_DEREF(z); - if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) { - ZVAL_UNDEF(var); - gc_possible_root(Z_COUNTED_P(z)); - } else { - ZVAL_UNDEF(var); - } - } - } else { - ZVAL_UNDEF(var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } varname = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); @@ -33672,33 +41065,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER( varname = &tmp; } - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + 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)) { - 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)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } - - HANDLE_EXCEPTION(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + 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)); + 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(); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + 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)); @@ -33707,103 +41103,87 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER( ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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; - if (IS_CV == IS_CV && - IS_VAR == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - 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))) { - 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(); - } else { - - zval tmp, *varname; - - SAVE_OPLINE(); - varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); - 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_UNUSED) { - zend_class_entry *ce; - - 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; - } + zval tmp, *varname; + zend_class_entry *ce; - goto is_var_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_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CV == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + SAVE_OPLINE(); + varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); + ZVAL_UNDEF(&tmp); + if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { + ZVAL_STR(&tmp, zval_get_string(varname)); + varname = &tmp; + } - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + 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*)); - goto is_var_return; - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; } - value = zend_std_get_static_property(ce, Z_STR_P(varname), 1); + 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_VM_NEXT_OPCODE_CHECK_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)); + } - if (IS_CV == IS_CONST && value) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value); + HANDLE_EXCEPTION(); } } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + if (IS_CV == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } -is_var_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); + goto is_static_prop_return; } + } - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + 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) @@ -33831,6 +41211,13 @@ try_instanceof: } 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)); + + HANDLE_EXCEPTION(); + } } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } @@ -33877,7 +41264,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND 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_CV == IS_TMP_VAR) { + if (IS_CV & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -33892,12 +41279,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND } else { zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_CV == IS_VAR && @@ -34006,12 +41387,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - - HANDLE_EXCEPTION(); - } dim = NULL; @@ -34029,22 +41404,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP zend_fetch_dimension_address_RW(&rv, container, dim, IS_UNUSED); value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - var_ptr = Z_INDIRECT(rv); - - if (UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - - FREE_OP(free_op_data1); - - HANDLE_EXCEPTION(); - } - if (UNEXPECTED(var_ptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR(rv))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { + ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); + var_ptr = Z_INDIRECT(rv); ZVAL_DEREF(var_ptr); SEPARATE_ZVAL_NOREF(var_ptr); @@ -34325,63 +41692,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_UNUSED == IS_CONST) { - if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { - retval = 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)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } - - goto fetch_var_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)) { - if (IS_CV != IS_CONST) { - zend_string_release(name); - } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CV == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - - HANDLE_EXCEPTION(); - } - - goto fetch_var_return; - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - if (IS_CV != IS_CONST) { - zend_string_release(name); - } - - HANDLE_EXCEPTION(); - } - if (IS_CV == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + retval = zend_hash_find(target_symbol_table, name); + if (retval == NULL) { + 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() } - - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { + /* 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) { switch (type) { case BP_VAR_R: case BP_VAR_UNSET: @@ -34392,52 +41726,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ 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; + /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + ZVAL_NULL(retval); 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) { - 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_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + } - HANDLE_EXCEPTION(); - } - } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { + if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - } } if (IS_CV != IS_CONST) { zend_string_release(name); } -fetch_var_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -34486,6 +41791,145 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CV_UNUSED_HANDLE 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; + zend_string *name; + zend_class_entry *ce; + + SAVE_OPLINE(); + varname = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); + + 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); + } + + if (IS_UNUSED == IS_CONST) { + if (IS_CV == IS_CONST && EXPECTED((ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) != NULL)) { + retval = 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)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); + } + + goto fetch_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)) { + if (IS_CV != IS_CONST) { + zend_string_release(name); + } + + ZEND_VM_NEXT_OPCODE_CHECK_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) { + zend_string_release(name); + } + + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if (IS_CV == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + + HANDLE_EXCEPTION(); + } + + goto fetch_static_prop_return; + } + } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + if (IS_CV != IS_CONST) { + zend_string_release(name); + } + + HANDLE_EXCEPTION(); + } + if (IS_CV == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } + + if (IS_CV != IS_CONST) { + zend_string_release(name); + } + +fetch_static_prop_return: + ZEND_ASSERT(retval != NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { + ZVAL_UNREF(retval); + } + ZVAL_COPY(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 @@ -34495,14 +41939,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HAN SAVE_OPLINE(); container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -34517,14 +41957,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HA SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -34539,21 +41975,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNU SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); HANDLE_EXCEPTION(); } container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -34572,12 +42003,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNU ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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; - zend_free_op free_op_data1; + zval *value; zval *variable_ptr; zval *dim; @@ -34585,13 +42016,102 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HAND SAVE_OPLINE(); object_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_UNUSED == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { + dim = NULL; + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_UNUSED, BP_VAR_W); - HANDLE_EXCEPTION(); + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + 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)) { + + zval *property_name = NULL; + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CONST, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_UNUSED == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = NULL; + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = EX_CONSTANT((opline+1)->op1); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } } + /* 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(execute_data, opline->op1.var); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: if (IS_UNUSED == IS_UNUSED) { @@ -34599,7 +42119,7 @@ try_assign_dim_array: 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"); - variable_ptr = &EG(error_zval); + variable_ptr = NULL; } } else { dim = NULL; @@ -34607,14 +42127,14 @@ try_assign_dim_array: variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_UNUSED, BP_VAR_W); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - FREE_OP(free_op_data1); + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + 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); } @@ -34630,13 +42150,13 @@ try_assign_dim_array: zval *property_name = NULL; - zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_TMP_VAR, (opline+1)->op1, execute_data); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { if (IS_UNUSED == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); HANDLE_EXCEPTION(); } else { @@ -34645,9 +42165,9 @@ try_assign_dim_array: dim = NULL; offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); - value = get_zval_ptr_r_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + zval_ptr_dtor_nogc(free_op_data); } } else { zval_ptr_dtor_nogc(object_ptr); @@ -34657,17 +42177,206 @@ assign_dim_convert_to_array: goto try_assign_dim_array; } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) { - goto assign_dim_clean; + goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + + /* 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(execute_data, opline->op1.var); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_UNUSED == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { + dim = NULL; + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_UNUSED, BP_VAR_W); + + } + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + 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)) { + + zval *property_name = NULL; + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_VAR, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_UNUSED == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = NULL; + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = _get_zval_ptr_var_deref((opline+1)->op1.var, execute_data, &free_op_data); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zval_ptr_dtor_nogc(free_op_data); + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; } else { zend_error(E_WARNING, "Cannot use a scalar value as an array"); assign_dim_clean: + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + + /* 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(execute_data, opline->op1.var); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_UNUSED == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { dim = NULL; + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_UNUSED, BP_VAR_W); + + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + 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)) { + + zval *property_name = NULL; + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CV, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_UNUSED == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = NULL; + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, (opline+1)->op1.var); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - FREE_OP(free_op_data1); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -34726,8 +42435,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU if (UNEXPECTED(EG(exception) != NULL)) { if (IS_CV == IS_CONST) { zval_ptr_dtor_nogc(retval_ptr); - } else { - } } #endif @@ -34745,11 +42452,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUS 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(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); @@ -34874,7 +42576,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDL SAVE_OPLINE(); if (IS_CV == IS_CV && - IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { zval *var = EX_VAR(opline->op1.var); @@ -34911,33 +42612,66 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDL varname = &tmp; } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); - 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)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { - zend_string_release(Z_STR(tmp)); - } + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); + } - HANDLE_EXCEPTION(); + 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(execute_data, opline->op1.var); + + 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)) { + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + 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)); + 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(); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + 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)); @@ -34953,7 +42687,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUS int result; if (IS_CV == IS_CV && - IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { value = EX_VAR(opline->op1.var); if (opline->extended_value & ZEND_ISSET) { @@ -34974,6 +42707,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUS } else { zval tmp, *varname; + HashTable *target_symbol_table; SAVE_OPLINE(); varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); @@ -34983,55 +42717,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUS varname = &tmp; } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; - - 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_var_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_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if (IS_CV == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_var_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); - } - } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); - } + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + 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)); } -is_var_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); @@ -35045,6 +42737,140 @@ is_var_return: } } +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(execute_data, opline->op1.var); + 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_VM_NEXT_OPCODE_CHECK_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)); + } + if (IS_CV == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* 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(execute_data, opline->op1.var); + +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 (UNEXPECTED(ce == NULL)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + + ZEND_VM_NEXT_OPCODE_CHECK_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)); + + 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 @@ -35072,7 +42898,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z 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_CV == IS_TMP_VAR) { + if (IS_CV & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -35087,12 +42913,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z } else { zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_CV == IS_VAR && @@ -35844,13 +43664,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - - HANDLE_EXCEPTION(); - } - do { value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); @@ -35868,7 +43681,7 @@ 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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -35908,12 +43721,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - - HANDLE_EXCEPTION(); - } dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); @@ -35931,22 +43738,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP zend_fetch_dimension_address_RW(&rv, container, dim, IS_CV); value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - var_ptr = Z_INDIRECT(rv); - if (UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - - FREE_OP(free_op_data1); - - HANDLE_EXCEPTION(); - } - - if (UNEXPECTED(var_ptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR(rv))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { + ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); + var_ptr = Z_INDIRECT(rv); ZVAL_DEREF(var_ptr); SEPARATE_ZVAL_NOREF(var_ptr); @@ -35974,13 +43773,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_C value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - - if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -36258,12 +44051,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -36279,7 +44066,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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -36342,12 +44129,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - - HANDLE_EXCEPTION(); - } - do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -36362,7 +44143,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP 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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) { @@ -36425,14 +44206,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER SAVE_OPLINE(); container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var), IS_CV); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -36447,14 +44224,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLE SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var), IS_CV); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -36483,21 +44256,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_ SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); HANDLE_EXCEPTION(); } container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var), IS_CV); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -36525,15 +44293,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HAN SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var), IS_CV); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -36627,16 +44390,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -36658,15 +44416,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLE HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -36763,21 +44516,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_ HANDLE_EXCEPTION(); } - if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -36803,26 +44551,115 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HAN property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - - HANDLE_EXCEPTION(); - } 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); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 0); + 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_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property_name; + + zval *container; + zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + + SAVE_OPLINE(); + container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); + +try_fetch_list: + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + zval *value; + zend_string *str; + zend_ulong hval; + +assign_again_list: + if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_list: + value = zend_hash_index_find(Z_ARRVAL_P(container), hval); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_list; + } + +str_index_list: + value = zend_hash_find(Z_ARRVAL_P(container), str); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str)); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (UNEXPECTED(str != Z_STR_P(offset))) { + zend_string_release(str); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto assign_again_list; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index_list; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset)); + hval = Z_RES_HANDLE_P(offset); + } else { + zend_error(E_WARNING, "Illegal offset type"); + } + } else if (IS_CV != IS_CONST && + UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) && + EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) { + zval *result = EX_VAR(opline->result.var); + zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result); + + if (retval) { + if (result != retval) { + ZVAL_COPY(result, retval); + } + } else { + ZVAL_NULL(result); + } + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + goto try_fetch_list; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + 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_name, *value, tmp; SAVE_OPLINE(); object = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); @@ -36834,25 +44671,696 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_HANDLER( } property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + value = EX_CONSTANT((opline+1)->op1); - if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + } while (0); + } + + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CONST != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CONST == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +exit_assign_obj: + + + /* 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) +{ + USE_OPLINE + zend_free_op free_op_data; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); HANDLE_EXCEPTION(); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_CV, property_name, IS_CV, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); + + property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_TMP_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + zval_ptr_dtor_nogc(free_op_data); + } +exit_assign_obj: /* 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_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_op_data; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + + HANDLE_EXCEPTION(); + } + + property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + zval_ptr_dtor_nogc(free_op_data); + } +exit_assign_obj: + + + /* 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) +{ + USE_OPLINE + + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + + HANDLE_EXCEPTION(); + } + + property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + } while (0); + } + + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CV != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CV == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +exit_assign_obj: + + + /* 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) { USE_OPLINE zval *object_ptr; - zend_free_op free_op_data1; + zval *value; zval *variable_ptr; zval *dim; @@ -36860,13 +45368,102 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER( SAVE_OPLINE(); object_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_CV == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CV, BP_VAR_W); - HANDLE_EXCEPTION(); + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + 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)) { + + zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CONST, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_CV == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = EX_CONSTANT((opline+1)->op1); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } } + /* 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) +{ + 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(execute_data, opline->op1.var); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: if (IS_CV == IS_UNUSED) { @@ -36874,7 +45471,7 @@ try_assign_dim_array: 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"); - variable_ptr = &EG(error_zval); + variable_ptr = NULL; } } else { dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); @@ -36882,14 +45479,14 @@ try_assign_dim_array: variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CV, BP_VAR_W); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - FREE_OP(free_op_data1); + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + 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); } @@ -36905,13 +45502,13 @@ try_assign_dim_array: zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_TMP_VAR, (opline+1)->op1, execute_data); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { if (IS_CV == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); HANDLE_EXCEPTION(); } else { @@ -36920,9 +45517,9 @@ try_assign_dim_array: dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); - value = get_zval_ptr_r_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + zval_ptr_dtor_nogc(free_op_data); } } else { zval_ptr_dtor_nogc(object_ptr); @@ -36932,17 +45529,206 @@ assign_dim_convert_to_array: goto try_assign_dim_array; } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) { - goto assign_dim_clean; + goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + + /* 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) +{ + 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(execute_data, opline->op1.var); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_CV == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CV, BP_VAR_W); + + } + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + 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)) { + + zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_VAR, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_CV == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = _get_zval_ptr_var_deref((opline+1)->op1.var, execute_data, &free_op_data); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zval_ptr_dtor_nogc(free_op_data); + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; } else { zend_error(E_WARNING, "Cannot use a scalar value as an array"); assign_dim_clean: + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + + /* 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) +{ + USE_OPLINE + + zval *object_ptr; + + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if (IS_CV == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CV, BP_VAR_W); + + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + 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)) { + + zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CV, (opline+1)->op1, execute_data); + + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if (IS_CV == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + + value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, (opline+1)->op1.var); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - FREE_OP(free_op_data1); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -36953,7 +45739,7 @@ assign_dim_clean: ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_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 @@ -36964,14 +45750,42 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (UNEXPECTED(0)) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { value = zend_assign_to_variable(variable_ptr, value, IS_CV); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + 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(execute_data, opline->op2.var); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + 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); } @@ -36990,51 +45804,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER( SAVE_OPLINE(); value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op2.var); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets nor overloaded objects"); - - HANDLE_EXCEPTION(); - } 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_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"); HANDLE_EXCEPTION(); - } - if (IS_CV == IS_VAR && - (value_ptr == &EG(uninitialized_zval) || - (opline->extended_value == ZEND_RETURNS_FUNCTION && - !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) { - if (!0 && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op2.var)) != IS_INDIRECT)) { /* undo the effect of get_zval_ptr_ptr() */ - Z_TRY_ADDREF_P(value_ptr); - } + + } else if (IS_CV == IS_VAR && + opline->extended_value == ZEND_RETURNS_FUNCTION && + UNEXPECTED(!(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) { + zend_error(E_NOTICE, "Only variables should be assigned by reference"); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } - ZEND_VM_TAIL_CALL(ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets nor overloaded objects"); + 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! */ - HANDLE_EXCEPTION(); - } - if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || - (IS_CV == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) { - 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 ((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(); } @@ -37309,11 +46119,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_H 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(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); @@ -37445,11 +46250,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(Z HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - - HANDLE_EXCEPTION(); - } offset = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); do { @@ -37541,11 +46341,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(Z HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - - HANDLE_EXCEPTION(); - } offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); do { @@ -37673,6 +46468,9 @@ num_index_prop: 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; @@ -37780,7 +46578,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_ 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_CV == IS_TMP_VAR) { + if (IS_CV & (IS_CONST|IS_TMP_VAR)) { zval *value; zend_error(E_NOTICE, "Only variable references should be yielded by reference"); @@ -37795,12 +46593,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_ } else { zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { - zend_throw_error(NULL, "Cannot yield string offsets by reference"); - - HANDLE_EXCEPTION(); - } - /* If a function call result is yielded and the function did * not return by reference we throw a notice. */ if (IS_CV == IS_VAR && @@ -38516,13 +47308,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } - do { value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); @@ -38540,7 +47325,7 @@ 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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -38580,12 +47365,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); @@ -38603,22 +47382,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SP zend_fetch_dimension_address_RW(&rv, container, dim, (IS_TMP_VAR|IS_VAR)); value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - var_ptr = Z_INDIRECT(rv); - - if (UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - zval_ptr_dtor_nogc(free_op2); - FREE_OP(free_op_data1); - HANDLE_EXCEPTION(); - } - - if (UNEXPECTED(var_ptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR(rv))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { + ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); + var_ptr = Z_INDIRECT(rv); ZVAL_DEREF(var_ptr); SEPARATE_ZVAL_NOREF(var_ptr); @@ -38647,13 +47418,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_C value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use assign-op operators with overloaded objects nor string offsets"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } - - if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -38932,12 +47697,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } - do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -38953,7 +47712,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)) { - if (UNEXPECTED(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -39017,12 +47776,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot increment/decrement overloaded objects nor string offsets"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } - do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { ZVAL_DEREF(object); @@ -39037,7 +47790,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP 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(zptr == &EG(error_zval))) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) { @@ -39101,14 +47854,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HAN SAVE_OPLINE(); container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR)); zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -39123,14 +47872,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HA SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR)); zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -39159,21 +47904,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP SAVE_OPLINE(); if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) { - if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { + if ((IS_CV & (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)); HANDLE_EXCEPTION(); } container = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR)); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } zval_ptr_dtor_nogc(free_op2); @@ -39201,15 +47941,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2), (IS_TMP_VAR|IS_VAR)); zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { - EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var), 1); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -39304,16 +48039,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HAN zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -39335,15 +48065,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HA zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -39441,21 +48166,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { zend_throw_error(NULL, "Cannot use temporary expression in write context"); zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } 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), 0); + EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -39481,26 +48201,115 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an object"); - zval_ptr_dtor_nogc(free_op2); - HANDLE_EXCEPTION(); - } 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), 0); + 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_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zend_free_op free_op2; - zval *object; - zval *property_name; + zval *container; + zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + + SAVE_OPLINE(); + container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); + +try_fetch_list: + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + zval *value; + zend_string *str; + zend_ulong hval; + +assign_again_list: + if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_list: + value = zend_hash_index_find(Z_ARRVAL_P(container), hval); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_list; + } + +str_index_list: + value = zend_hash_find(Z_ARRVAL_P(container), str); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str)); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (UNEXPECTED(str != Z_STR_P(offset))) { + zend_string_release(str); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto assign_again_list; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index_list; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset)); + hval = Z_RES_HANDLE_P(offset); + } else { + zend_error(E_WARNING, "Illegal offset type"); + } + } else if (IS_CV != IS_CONST && + UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) && + EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) { + zval *result = EX_VAR(opline->result.var); + zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result); + + if (retval) { + if (result != retval) { + ZVAL_COPY(result, retval); + } + } else { + ZVAL_NULL(result); + } + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + goto try_fetch_list; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + ZVAL_NULL(EX_VAR(opline->result.var)); + } + 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_name, *value, tmp; SAVE_OPLINE(); object = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); @@ -39512,25 +48321,696 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_HAND } property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + value = EX_CONSTANT((opline+1)->op1); - if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - zval_ptr_dtor_nogc(free_op2); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CONST != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CONST == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +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) +{ + USE_OPLINE + zend_free_op free_op2, free_op_data; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } + + property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_TMP_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + 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) +{ + USE_OPLINE + zend_free_op free_op2, free_op_data; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } + + property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + 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 (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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + zval_ptr_dtor_nogc(free_op_data); + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_VAR != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_VAR == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + 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) +{ + USE_OPLINE + zend_free_op free_op2; + zval *object, *property_name, *value, tmp; + + SAVE_OPLINE(); + object = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { + zend_throw_error(NULL, "Using $this when not in object context"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_CV, property_name, (IS_TMP_VAR|IS_VAR), (opline+1)->op1_type, (opline+1)->op1, execute_data, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); + + property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + do { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + 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 { + zend_error(E_WARNING, "Attempt to assign property of non-object"); + 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_name)))) { + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property_name) + sizeof(void*)); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { + property = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign_obj: + value = zend_assign_to_variable(property, 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 = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set) { + + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } 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_name), 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_error(E_WARNING, "Attempt to assign property of non-object"); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + goto exit_assign_obj; + } + + /* separate our value if necessary */ + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (IS_CV != IS_TMP_VAR) { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object)->write_property(object, property_name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL); + + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && EXPECTED(!EG(exception))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (IS_CV == IS_CONST) { + zval_ptr_dtor_nogc(value); + } else { + + } +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_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, free_op_data1; + zend_free_op free_op2; zval *value; zval *variable_ptr; zval *dim; @@ -39538,13 +49018,102 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_HAND SAVE_OPLINE(); object_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) { - zend_throw_error(NULL, "Cannot use string offset as an array"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + 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)) { + zend_free_op free_op2; + zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CONST, (opline+1)->op1, execute_data); + zval_ptr_dtor_nogc(free_op2); + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + value = EX_CONSTANT((opline+1)->op1); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } } + /* 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) +{ + USE_OPLINE + + 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_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { @@ -39552,7 +49121,7 @@ try_assign_dim_array: 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"); - variable_ptr = &EG(error_zval); + variable_ptr = NULL; } } else { dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); @@ -39560,14 +49129,14 @@ try_assign_dim_array: variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_W); zval_ptr_dtor_nogc(free_op2); } - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - FREE_OP(free_op_data1); + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); + 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); } @@ -39583,13 +49152,13 @@ try_assign_dim_array: zend_free_op free_op2; zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_TMP_VAR, (opline+1)->op1, execute_data); zval_ptr_dtor_nogc(free_op2); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_throw_error(NULL, "[] operator not supported for strings"); - FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); HANDLE_EXCEPTION(); } else { @@ -39598,9 +49167,9 @@ try_assign_dim_array: dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); zval_ptr_dtor_nogc(free_op2); - value = get_zval_ptr_r_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); + value = _get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data); zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + zval_ptr_dtor_nogc(free_op_data); } } else { zval_ptr_dtor_nogc(object_ptr); @@ -39610,17 +49179,206 @@ assign_dim_convert_to_array: goto try_assign_dim_array; } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == &EG(error_zval))) { - goto assign_dim_clean; + goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + + /* 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) +{ + USE_OPLINE + + 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_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + } + if (UNEXPECTED(variable_ptr == NULL)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data); + 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)) { + zend_free_op free_op2; + zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_VAR, (opline+1)->op1, execute_data); + zval_ptr_dtor_nogc(free_op2); + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + 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)); + + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + value = _get_zval_ptr_var_deref((opline+1)->op1.var, execute_data, &free_op_data); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + zval_ptr_dtor_nogc(free_op_data); + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; } else { zend_error(E_WARNING, "Cannot use a scalar value as an array"); assign_dim_clean: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + + /* 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) +{ + USE_OPLINE + + zval *object_ptr; + zend_free_op free_op2; + zval *value; + zval *variable_ptr; + zval *dim; + + SAVE_OPLINE(); + object_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + 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"); + variable_ptr = NULL; + } + } else { dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_W); zval_ptr_dtor_nogc(free_op2); - value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1); - FREE_OP(free_op_data1); + } + if (UNEXPECTED(variable_ptr == NULL)) { + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + value = _get_zval_ptr_cv_BP_VAR_R(execute_data, (opline+1)->op1.var); + 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)) { + zend_free_op free_op2; + zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + + zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, IS_CV, (opline+1)->op1, execute_data); + zval_ptr_dtor_nogc(free_op2); + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + zend_throw_error(NULL, "[] operator not supported for strings"); + + + HANDLE_EXCEPTION(); + } else { + zend_long offset; + + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, (opline+1)->op1.var); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + + } + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + 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 (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + goto assign_dim_convert_to_array; + } else if (IS_CV == IS_VAR && UNEXPECTED(Z_ISERROR_P(object_ptr))) { + goto assign_dim_clean; + } else { + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } @@ -39902,11 +49660,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPV 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(execute_data, opline->op1.var); - if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { - zend_throw_error(NULL, "Cannot create references to/from string offsets"); - zend_array_destroy(Z_ARRVAL_P(EX_VAR(opline->result.var))); - HANDLE_EXCEPTION(); - } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); @@ -40038,11 +49791,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDL zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); do { @@ -40135,11 +49883,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDL zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); do { @@ -40268,6 +50011,9 @@ num_index_prop: 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; @@ -40372,7 +50118,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER(Z 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 (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + 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(); @@ -40639,7 +50385,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_TMPVAR_HANDLER(ZEND_ 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 (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + 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(); @@ -40692,19 +50438,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND } while (0); ce = Z_OBJCE_P(obj); - clone = ce ? ce->clone : NULL; - clone_call = Z_OBJ_HT_P(obj)->clone_obj; + clone = ce->clone; + clone_call = Z_OBJ_HT_P(obj)->clone_obj; if (UNEXPECTED(clone_call == NULL)) { - if (ce) { - zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); - } else { - zend_throw_error(NULL, "Trying to clone an uncloneable object"); - } + zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } - if (ce && clone) { + 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. */ @@ -40724,12 +50466,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND } } - if (EXPECTED(EG(exception) == NULL)) { - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); - if (UNEXPECTED(!RETURN_VALUE_USED(opline)) || UNEXPECTED(EG(exception) != NULL)) { - OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); - } + ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj)); + if (UNEXPECTED(EG(exception) != NULL)) { + OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); } + zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -41536,14 +51277,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HAN ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMPVAR_CONST(int type ZEND_OPCODE_HANDLER_ARGS_DC) +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; zend_string *name; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); @@ -41560,120 +51301,75 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - 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)) { - retval = 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)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } + 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)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto fetch_var_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)) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(name); - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); + goto fetch_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)) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_string_release(name); } - - goto fetch_var_return; + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(name); - } - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); - } - - zval_ptr_dtor_nogc(free_op1); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { - 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) { - 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 (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_string_release(name); } + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - zval_ptr_dtor_nogc(free_op1); + + goto fetch_static_prop_return; } } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_string_release(name); + } + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } + + zval_ptr_dtor_nogc(free_op1); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_string_release(name); } -fetch_var_return: +fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -41686,40 +51382,40 @@ fetch_var_return: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_TMPVAR_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_W_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_TMPVAR_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_RW_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_TMPVAR_CONST(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_FUNC_ARG_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_TMPVAR_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_var_address_helper_SPEC_TMPVAR_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_UNSET_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_TMPVAR_CONST(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_TMPVAR_CONST(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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) @@ -41826,26 +51522,76 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_H { USE_OPLINE zend_free_op free_op1; + zval *container; + zval *offset = EX_CONSTANT(opline->op2); SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); try_fetch_list: if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - zval *value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2))); + zval *value; + zend_string *str; + zend_ulong hval; - if (UNEXPECTED(value == NULL)) { - zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2))); - ZVAL_NULL(EX_VAR(opline->result.var)); +assign_again_list: + if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_list: + value = zend_hash_index_find(Z_ARRVAL_P(container), hval); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_list; + } + +str_index_list: + value = zend_hash_find(Z_ARRVAL_P(container), str); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str)); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (UNEXPECTED(str != Z_STR_P(offset))) { + zend_string_release(str); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto assign_again_list; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index_list; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset)); + hval = Z_RES_HANDLE_P(offset); } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); + zend_error(E_WARNING, "Illegal offset type"); } } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) && EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) { zval *result = EX_VAR(opline->result.var); - zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, EX_CONSTANT(opline->op2), BP_VAR_R, result); + zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result); if (retval) { if (result != retval) { @@ -41863,6 +51609,7 @@ try_fetch_list: } ZVAL_NULL(EX_VAR(opline->result.var)); } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -42127,40 +51874,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval tmp, *varname; - HashTable *target_symbol_table; + zend_class_entry *ce; zend_free_op free_op1; SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && - IS_CONST == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - zval *var = EX_VAR(opline->op1.var); - - if (Z_REFCOUNTED_P(var)) { - zend_refcounted *garbage = Z_COUNTED_P(var); - - if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); - zval_dtor_func_for_ptr(garbage); - } else { - zval *z = var; - ZVAL_DEREF(z); - if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) { - ZVAL_UNDEF(var); - gc_possible_root(Z_COUNTED_P(z)); - } else { - ZVAL_UNDEF(var); - } - } - } else { - ZVAL_UNDEF(var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); @@ -42173,33 +51894,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_CONST_HA varname = &tmp; } - if (IS_CONST != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + 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)) { - 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)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - 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(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + 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)); + 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(); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + 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)); @@ -42208,104 +51932,88 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_CONST_HA ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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; - if ((IS_TMP_VAR|IS_VAR) == IS_CV && - IS_CONST == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - 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))) { - 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(); - } else { - zend_free_op free_op1; - zval tmp, *varname; - - SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - 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_UNUSED) { - zend_class_entry *ce; - - 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_var_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_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + 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; + } - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + 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*)); - goto is_var_return; - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; } - 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); + 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_VM_NEXT_OPCODE_CHECK_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 { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - 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); + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } -is_var_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); + goto is_static_prop_return; } + } - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + 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) @@ -42411,6 +52119,9 @@ num_index_prop: 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; @@ -42516,6 +52227,13 @@ try_instanceof: } 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); + HANDLE_EXCEPTION(); + } } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } @@ -42535,14 +52253,14 @@ try_instanceof: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMPVAR_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) +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; zend_string *name; - HashTable *target_symbol_table; + zend_class_entry *ce; SAVE_OPLINE(); varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); @@ -42559,120 +52277,75 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - 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)) { - retval = 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)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } + 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)) { + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); - goto fetch_var_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)) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(name); - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); + goto fetch_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)) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_string_release(name); } - - goto fetch_var_return; - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(name); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); } - - zval_ptr_dtor_nogc(free_op1); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { - 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) { - 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 (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_string_release(name); } + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - zval_ptr_dtor_nogc(free_op1); + + goto fetch_static_prop_return; } } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_string_release(name); + } + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } + + zval_ptr_dtor_nogc(free_op1); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_string_release(name); } -fetch_var_return: +fetch_static_prop_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -42685,76 +52358,50 @@ fetch_var_return: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_R_SPEC_TMPVAR_VAR_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_var_address_helper_SPEC_TMPVAR_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_W_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_TMPVAR_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_RW_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_TMPVAR_VAR(BP_VAR_RW ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_FUNC_ARG_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_TMPVAR_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_var_address_helper_SPEC_TMPVAR_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_UNSET_SPEC_TMPVAR_VAR_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_var_address_helper_SPEC_TMPVAR_VAR(BP_VAR_UNSET ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_IS_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +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_var_address_helper_SPEC_TMPVAR_VAR(BP_VAR_IS ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); + 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_VAR_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval tmp, *varname; - HashTable *target_symbol_table; + zend_class_entry *ce; zend_free_op free_op1; SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && - IS_VAR == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - zval *var = EX_VAR(opline->op1.var); - - if (Z_REFCOUNTED_P(var)) { - zend_refcounted *garbage = Z_COUNTED_P(var); - - if (!--GC_REFCOUNT(garbage)) { - ZVAL_UNDEF(var); - zval_dtor_func_for_ptr(garbage); - } else { - zval *z = var; - ZVAL_DEREF(z); - if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) { - ZVAL_UNDEF(var); - gc_possible_root(Z_COUNTED_P(z)); - } else { - ZVAL_UNDEF(var); - } - } - } else { - ZVAL_UNDEF(var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); @@ -42767,33 +52414,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_VAR_HAND varname = &tmp; } - if (IS_VAR != IS_UNUSED) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + 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)) { - 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)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - 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(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + 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)); + 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(); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + 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)); @@ -42802,104 +52452,88 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_VAR_HAND ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_VAR_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 *value; int result; + zend_free_op free_op1; + zval tmp, *varname; + zend_class_entry *ce; - if ((IS_TMP_VAR|IS_VAR) == IS_CV && - IS_VAR == IS_UNUSED && - (opline->extended_value & ZEND_QUICK_SET)) { - 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))) { - 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(); - } else { - zend_free_op free_op1; - zval tmp, *varname; - - SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - 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_UNUSED) { - zend_class_entry *ce; - - 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_var_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_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + 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; + } - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } + 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*)); - goto is_var_return; - } + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; } - 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); + 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_VM_NEXT_OPCODE_CHECK_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 { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); + ce = Z_CE_P(EX_VAR(opline->op2.var)); } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - 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); + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + value = NULL; + } -is_var_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); + goto is_static_prop_return; } + } - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + 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) @@ -42927,6 +52561,13 @@ try_instanceof: } 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); + HANDLE_EXCEPTION(); + } } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } @@ -42970,64 +52611,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ name = zval_get_string(varname); } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; - - 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)) { - retval = 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)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - - goto fetch_var_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)) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(name); - } - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - - goto fetch_var_return; - } - } - retval = zend_std_get_static_property(ce, name, 0); - if (UNEXPECTED(EG(exception))) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release(name); - } - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && retval) { - CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + retval = zend_hash_find(target_symbol_table, name); + if (retval == NULL) { + 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() } - - zval_ptr_dtor_nogc(free_op1); - } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - retval = zend_hash_find(target_symbol_table, name); - if (retval == NULL) { + /* 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) { switch (type) { case BP_VAR_R: case BP_VAR_UNSET: @@ -43038,52 +52645,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ 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; + /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + ZVAL_NULL(retval); 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) { - 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_STATIC) { - if (Z_CONSTANT_P(retval)) { - if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - } - } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - zval_ptr_dtor_nogc(free_op1); } } + 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); } -fetch_var_return: ZEND_ASSERT(retval != NULL); if (type == BP_VAR_R || type == BP_VAR_IS) { if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { @@ -43132,6 +52710,147 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HA 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; + zend_string *name; + zend_class_entry *ce; + + SAVE_OPLINE(); + varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + + 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); + } + + 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)) { + retval = 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)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + + goto fetch_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)) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_string_release(name); + } + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_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) { + zend_string_release(name); + } + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + (retval = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* check if static properties were destoyed */ + if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { + zend_throw_error(NULL, "Access to undeclared static property: %s::$%s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + + goto fetch_static_prop_return; + } + } + retval = zend_std_get_static_property(ce, name, 0); + if (UNEXPECTED(EG(exception))) { + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_string_release(name); + } + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && retval) { + CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, retval); + } + + zval_ptr_dtor_nogc(free_op1); + + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_string_release(name); + } + +fetch_static_prop_return: + ZEND_ASSERT(retval != NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + if (/*type == BP_VAR_R &&*/ Z_ISREF_P(retval) && Z_REFCOUNT_P(retval) == 1) { + ZVAL_UNREF(retval); + } + ZVAL_COPY(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 @@ -43141,7 +52860,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_H SAVE_OPLINE(); if ((IS_TMP_VAR|IS_VAR) == IS_CV && - IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { zval *var = EX_VAR(opline->op1.var); @@ -43178,33 +52896,66 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_H varname = &tmp; } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); + 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, execute_data, &free_op1); + + 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)) { - 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)) { - if (EXPECTED(!EG(exception))) { - zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } - 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(); + if (EXPECTED(!EG(exception))) { + zend_throw_error(NULL, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); + 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)); + 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(); } - zend_std_unset_static_property(ce, Z_STR_P(varname)); } else { - target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); + 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)); @@ -43220,7 +52971,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_ int result; if ((IS_TMP_VAR|IS_VAR) == IS_CV && - IS_UNUSED == IS_UNUSED && (opline->extended_value & ZEND_QUICK_SET)) { value = EX_VAR(opline->op1.var); if (opline->extended_value & ZEND_ISSET) { @@ -43241,6 +52991,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_ } else { zend_free_op free_op1; zval tmp, *varname; + HashTable *target_symbol_table; SAVE_OPLINE(); varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); @@ -43250,56 +53001,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_ varname = &tmp; } - if (IS_UNUSED != IS_UNUSED) { - zend_class_entry *ce; - - 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_var_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_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { - - /* check if static properties were destoyed */ - if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { - value = NULL; - } - - goto is_var_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); - } - } else { - HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); - value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); - } + target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK); + 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); -is_var_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); @@ -43313,6 +53022,141 @@ is_var_return: } } +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, execute_data, &free_op1); + 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_VM_NEXT_OPCODE_CHECK_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)); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) { + + /* 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, execute_data, &free_op1); + +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 (UNEXPECTED(ce == NULL)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_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)); + zval_ptr_dtor_nogc(free_op1); + 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 @@ -44014,6 +53858,101 @@ fetch_obj_is_no_object: 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; + zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + +try_fetch_list: + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + zval *value; + zend_string *str; + zend_ulong hval; + +assign_again_list: + if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_list: + value = zend_hash_index_find(Z_ARRVAL_P(container), hval); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_list; + } + +str_index_list: + value = zend_hash_find(Z_ARRVAL_P(container), str); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str)); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (UNEXPECTED(str != Z_STR_P(offset))) { + zend_string_release(str); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto assign_again_list; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index_list; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset)); + hval = Z_RES_HANDLE_P(offset); + } else { + zend_error(E_WARNING, "Illegal offset type"); + } + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && + UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) && + EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) { + zval *result = EX_VAR(opline->result.var); + zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result); + + if (retval) { + if (result != retval) { + ZVAL_COPY(result, retval); + } + } else { + ZVAL_NULL(result); + } + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + goto try_fetch_list; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + ZVAL_NULL(EX_VAR(opline->result.var)); + } + + 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 @@ -44378,6 +54317,9 @@ num_index_prop: 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; @@ -45160,6 +55102,101 @@ fetch_obj_is_no_object: 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; + zend_free_op free_op2; + zval *container; + zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + +try_fetch_list: + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + zval *value; + zend_string *str; + zend_ulong hval; + +assign_again_list: + if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_list: + value = zend_hash_index_find(Z_ARRVAL_P(container), hval); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_list; + } + +str_index_list: + value = zend_hash_find(Z_ARRVAL_P(container), str); + + if (UNEXPECTED(value == NULL)) { + zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str)); + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (UNEXPECTED(str != Z_STR_P(offset))) { + zend_string_release(str); + } + } else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto assign_again_list; + } else if (Z_TYPE_P(offset) == IS_NULL) { + str = ZSTR_EMPTY_ALLOC(); + goto str_index_list; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval(Z_DVAL_P(offset)); + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_list; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset)); + hval = Z_RES_HANDLE_P(offset); + } else { + zend_error(E_WARNING, "Illegal offset type"); + } + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && + UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) && + EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) { + zval *result = EX_VAR(opline->result.var); + zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result); + + if (retval) { + if (result != retval) { + ZVAL_COPY(result, retval); + } + } else { + ZVAL_NULL(result); + } + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + goto try_fetch_list; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + GET_OP1_UNDEF_CV(container, BP_VAR_R); + } + ZVAL_NULL(EX_VAR(opline->result.var)); + } + 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 @@ -45525,6 +55562,9 @@ num_index_prop: 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; @@ -45606,6 +55646,924 @@ isset_no_object: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -45617,4358 +56575,4121 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDL void zend_init_opcodes_handlers(void) { - static const void *labels[] = { - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_NOP_SPEC_HANDLER, - ZEND_ADD_SPEC_CONST_CONST_HANDLER, - ZEND_ADD_SPEC_CONST_TMPVAR_HANDLER, - ZEND_ADD_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ADD_SPEC_CONST_CV_HANDLER, - ZEND_ADD_SPEC_TMPVAR_CONST_HANDLER, - ZEND_ADD_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_ADD_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ADD_SPEC_TMPVAR_CV_HANDLER, - ZEND_ADD_SPEC_TMPVAR_CONST_HANDLER, - ZEND_ADD_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_ADD_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ADD_SPEC_TMPVAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ADD_SPEC_CV_CONST_HANDLER, - ZEND_ADD_SPEC_CV_TMPVAR_HANDLER, - ZEND_ADD_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ADD_SPEC_CV_CV_HANDLER, - ZEND_SUB_SPEC_CONST_CONST_HANDLER, - ZEND_SUB_SPEC_CONST_TMPVAR_HANDLER, - ZEND_SUB_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SUB_SPEC_CONST_CV_HANDLER, - ZEND_SUB_SPEC_TMPVAR_CONST_HANDLER, - ZEND_SUB_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_SUB_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SUB_SPEC_TMPVAR_CV_HANDLER, - ZEND_SUB_SPEC_TMPVAR_CONST_HANDLER, - ZEND_SUB_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_SUB_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SUB_SPEC_TMPVAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SUB_SPEC_CV_CONST_HANDLER, - ZEND_SUB_SPEC_CV_TMPVAR_HANDLER, - ZEND_SUB_SPEC_CV_TMPVAR_HANDLER, - 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_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_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, - ZEND_NULL_HANDLER, - ZEND_MUL_SPEC_CV_CONST_HANDLER, - ZEND_MUL_SPEC_CV_TMPVAR_HANDLER, - ZEND_MUL_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_MUL_SPEC_CV_CV_HANDLER, - ZEND_DIV_SPEC_CONST_CONST_HANDLER, - ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER, - ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_DIV_SPEC_CONST_CV_HANDLER, - ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER, - ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_DIV_SPEC_TMPVAR_CV_HANDLER, - ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER, - ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_DIV_SPEC_TMPVAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_DIV_SPEC_CV_CONST_HANDLER, - ZEND_DIV_SPEC_CV_TMPVAR_HANDLER, - ZEND_DIV_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_DIV_SPEC_CV_CV_HANDLER, - ZEND_MOD_SPEC_CONST_CONST_HANDLER, - ZEND_MOD_SPEC_CONST_TMPVAR_HANDLER, - ZEND_MOD_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_MOD_SPEC_CONST_CV_HANDLER, - ZEND_MOD_SPEC_TMPVAR_CONST_HANDLER, - ZEND_MOD_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_MOD_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_MOD_SPEC_TMPVAR_CV_HANDLER, - ZEND_MOD_SPEC_TMPVAR_CONST_HANDLER, - ZEND_MOD_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_MOD_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_MOD_SPEC_TMPVAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_MOD_SPEC_CV_CONST_HANDLER, - ZEND_MOD_SPEC_CV_TMPVAR_HANDLER, - ZEND_MOD_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_MOD_SPEC_CV_CV_HANDLER, - ZEND_SL_SPEC_CONST_CONST_HANDLER, - ZEND_SL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_SL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SL_SPEC_CONST_CV_HANDLER, - ZEND_SL_SPEC_TMPVAR_CONST_HANDLER, - ZEND_SL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_SL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SL_SPEC_TMPVAR_CV_HANDLER, - ZEND_SL_SPEC_TMPVAR_CONST_HANDLER, - ZEND_SL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_SL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SL_SPEC_TMPVAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SL_SPEC_CV_CONST_HANDLER, - ZEND_SL_SPEC_CV_TMPVAR_HANDLER, - ZEND_SL_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SL_SPEC_CV_CV_HANDLER, - ZEND_SR_SPEC_CONST_CONST_HANDLER, - ZEND_SR_SPEC_CONST_TMPVAR_HANDLER, - ZEND_SR_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SR_SPEC_CONST_CV_HANDLER, - ZEND_SR_SPEC_TMPVAR_CONST_HANDLER, - ZEND_SR_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_SR_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SR_SPEC_TMPVAR_CV_HANDLER, - ZEND_SR_SPEC_TMPVAR_CONST_HANDLER, - ZEND_SR_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_SR_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SR_SPEC_TMPVAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SR_SPEC_CV_CONST_HANDLER, - ZEND_SR_SPEC_CV_TMPVAR_HANDLER, - ZEND_SR_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SR_SPEC_CV_CV_HANDLER, - ZEND_CONCAT_SPEC_CONST_CONST_HANDLER, - ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER, - ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CONCAT_SPEC_CONST_CV_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CONCAT_SPEC_CV_CONST_HANDLER, - ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER, - ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER, - 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_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_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, - ZEND_NULL_HANDLER, - ZEND_BW_OR_SPEC_CV_CONST_HANDLER, - ZEND_BW_OR_SPEC_CV_TMPVAR_HANDLER, - ZEND_BW_OR_SPEC_CV_TMPVAR_HANDLER, - 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_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_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, - ZEND_NULL_HANDLER, - ZEND_BW_AND_SPEC_CV_CONST_HANDLER, - ZEND_BW_AND_SPEC_CV_TMPVAR_HANDLER, - ZEND_BW_AND_SPEC_CV_TMPVAR_HANDLER, - 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_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_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, - ZEND_NULL_HANDLER, - ZEND_BW_XOR_SPEC_CV_CONST_HANDLER, - ZEND_BW_XOR_SPEC_CV_TMPVAR_HANDLER, - ZEND_BW_XOR_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_BW_XOR_SPEC_CV_CV_HANDLER, - ZEND_BW_NOT_SPEC_CONST_HANDLER, - ZEND_BW_NOT_SPEC_CONST_HANDLER, - ZEND_BW_NOT_SPEC_CONST_HANDLER, - ZEND_BW_NOT_SPEC_CONST_HANDLER, - ZEND_BW_NOT_SPEC_CONST_HANDLER, - ZEND_BW_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BW_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BW_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BW_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BW_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BW_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BW_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BW_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BW_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BW_NOT_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_BW_NOT_SPEC_CV_HANDLER, - ZEND_BW_NOT_SPEC_CV_HANDLER, - ZEND_BW_NOT_SPEC_CV_HANDLER, - ZEND_BW_NOT_SPEC_CV_HANDLER, - ZEND_BW_NOT_SPEC_CV_HANDLER, - ZEND_BOOL_NOT_SPEC_CONST_HANDLER, - ZEND_BOOL_NOT_SPEC_CONST_HANDLER, - ZEND_BOOL_NOT_SPEC_CONST_HANDLER, - ZEND_BOOL_NOT_SPEC_CONST_HANDLER, - ZEND_BOOL_NOT_SPEC_CONST_HANDLER, - ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_BOOL_NOT_SPEC_CV_HANDLER, - ZEND_BOOL_NOT_SPEC_CV_HANDLER, - ZEND_BOOL_NOT_SPEC_CV_HANDLER, - ZEND_BOOL_NOT_SPEC_CV_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_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_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, - ZEND_NULL_HANDLER, - ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER, - ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER, - ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER, - 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_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_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, - ZEND_NULL_HANDLER, - ZEND_IS_IDENTICAL_SPEC_CV_CONST_HANDLER, - ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER, - ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER, - 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_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_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, - ZEND_NULL_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER, - 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_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_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, - ZEND_NULL_HANDLER, - ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER, - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER, - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER, - 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_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_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, - ZEND_NULL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLER, - ZEND_IS_SMALLER_SPEC_CONST_CONST_HANDLER, - ZEND_IS_SMALLER_SPEC_CONST_TMPVAR_HANDLER, - ZEND_IS_SMALLER_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_IS_SMALLER_SPEC_CONST_CV_HANDLER, - ZEND_IS_SMALLER_SPEC_TMPVAR_CONST_HANDLER, - ZEND_IS_SMALLER_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_IS_SMALLER_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_IS_SMALLER_SPEC_TMPVAR_CV_HANDLER, - ZEND_IS_SMALLER_SPEC_TMPVAR_CONST_HANDLER, - ZEND_IS_SMALLER_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_IS_SMALLER_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_IS_SMALLER_SPEC_TMPVAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_IS_SMALLER_SPEC_CV_CONST_HANDLER, - ZEND_IS_SMALLER_SPEC_CV_TMPVAR_HANDLER, - ZEND_IS_SMALLER_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_IS_SMALLER_SPEC_CV_CV_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CV_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CONST_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CV_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CONST_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CONST_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMPVAR_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CV_HANDLER, - ZEND_CAST_SPEC_CONST_HANDLER, - ZEND_CAST_SPEC_CONST_HANDLER, - ZEND_CAST_SPEC_CONST_HANDLER, - ZEND_CAST_SPEC_CONST_HANDLER, - ZEND_CAST_SPEC_CONST_HANDLER, - ZEND_CAST_SPEC_TMP_HANDLER, - ZEND_CAST_SPEC_TMP_HANDLER, - ZEND_CAST_SPEC_TMP_HANDLER, - ZEND_CAST_SPEC_TMP_HANDLER, - ZEND_CAST_SPEC_TMP_HANDLER, - ZEND_CAST_SPEC_VAR_HANDLER, - ZEND_CAST_SPEC_VAR_HANDLER, - ZEND_CAST_SPEC_VAR_HANDLER, - ZEND_CAST_SPEC_VAR_HANDLER, - ZEND_CAST_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CAST_SPEC_CV_HANDLER, - ZEND_CAST_SPEC_CV_HANDLER, - ZEND_CAST_SPEC_CV_HANDLER, - ZEND_CAST_SPEC_CV_HANDLER, - ZEND_CAST_SPEC_CV_HANDLER, - ZEND_QM_ASSIGN_SPEC_CONST_HANDLER, - ZEND_QM_ASSIGN_SPEC_CONST_HANDLER, - ZEND_QM_ASSIGN_SPEC_CONST_HANDLER, - ZEND_QM_ASSIGN_SPEC_CONST_HANDLER, - ZEND_QM_ASSIGN_SPEC_CONST_HANDLER, - ZEND_QM_ASSIGN_SPEC_TMP_HANDLER, - ZEND_QM_ASSIGN_SPEC_TMP_HANDLER, - ZEND_QM_ASSIGN_SPEC_TMP_HANDLER, - ZEND_QM_ASSIGN_SPEC_TMP_HANDLER, - ZEND_QM_ASSIGN_SPEC_TMP_HANDLER, - ZEND_QM_ASSIGN_SPEC_VAR_HANDLER, - ZEND_QM_ASSIGN_SPEC_VAR_HANDLER, - ZEND_QM_ASSIGN_SPEC_VAR_HANDLER, - ZEND_QM_ASSIGN_SPEC_VAR_HANDLER, - ZEND_QM_ASSIGN_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_QM_ASSIGN_SPEC_CV_HANDLER, - ZEND_QM_ASSIGN_SPEC_CV_HANDLER, - ZEND_QM_ASSIGN_SPEC_CV_HANDLER, - ZEND_QM_ASSIGN_SPEC_CV_HANDLER, - ZEND_QM_ASSIGN_SPEC_CV_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_NULL_HANDLER, - ZEND_ASSIGN_ADD_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_ADD_SPEC_VAR_UNUSED_HANDLER, - ZEND_ASSIGN_ADD_SPEC_VAR_CV_HANDLER, - ZEND_ASSIGN_ADD_SPEC_UNUSED_CONST_HANDLER, - ZEND_ASSIGN_ADD_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_ADD_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_ADD_SPEC_UNUSED_UNUSED_HANDLER, - ZEND_ASSIGN_ADD_SPEC_UNUSED_CV_HANDLER, - ZEND_ASSIGN_ADD_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_ADD_SPEC_CV_UNUSED_HANDLER, - ZEND_ASSIGN_ADD_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_ASSIGN_SUB_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_SUB_SPEC_VAR_UNUSED_HANDLER, - ZEND_ASSIGN_SUB_SPEC_VAR_CV_HANDLER, - ZEND_ASSIGN_SUB_SPEC_UNUSED_CONST_HANDLER, - ZEND_ASSIGN_SUB_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_SUB_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_SUB_SPEC_UNUSED_UNUSED_HANDLER, - ZEND_ASSIGN_SUB_SPEC_UNUSED_CV_HANDLER, - ZEND_ASSIGN_SUB_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_SUB_SPEC_CV_UNUSED_HANDLER, - ZEND_ASSIGN_SUB_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_ASSIGN_MUL_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_MUL_SPEC_VAR_UNUSED_HANDLER, - ZEND_ASSIGN_MUL_SPEC_VAR_CV_HANDLER, - ZEND_ASSIGN_MUL_SPEC_UNUSED_CONST_HANDLER, - ZEND_ASSIGN_MUL_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_MUL_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_MUL_SPEC_UNUSED_UNUSED_HANDLER, - ZEND_ASSIGN_MUL_SPEC_UNUSED_CV_HANDLER, - ZEND_ASSIGN_MUL_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_MUL_SPEC_CV_UNUSED_HANDLER, - ZEND_ASSIGN_MUL_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_ASSIGN_DIV_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_DIV_SPEC_VAR_UNUSED_HANDLER, - ZEND_ASSIGN_DIV_SPEC_VAR_CV_HANDLER, - ZEND_ASSIGN_DIV_SPEC_UNUSED_CONST_HANDLER, - ZEND_ASSIGN_DIV_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_DIV_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_DIV_SPEC_UNUSED_UNUSED_HANDLER, - ZEND_ASSIGN_DIV_SPEC_UNUSED_CV_HANDLER, - ZEND_ASSIGN_DIV_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_DIV_SPEC_CV_UNUSED_HANDLER, - ZEND_ASSIGN_DIV_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_ASSIGN_MOD_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_MOD_SPEC_VAR_UNUSED_HANDLER, - ZEND_ASSIGN_MOD_SPEC_VAR_CV_HANDLER, - ZEND_ASSIGN_MOD_SPEC_UNUSED_CONST_HANDLER, - ZEND_ASSIGN_MOD_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_MOD_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_MOD_SPEC_UNUSED_UNUSED_HANDLER, - ZEND_ASSIGN_MOD_SPEC_UNUSED_CV_HANDLER, - ZEND_ASSIGN_MOD_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_MOD_SPEC_CV_UNUSED_HANDLER, - ZEND_ASSIGN_MOD_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_ASSIGN_SL_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_SL_SPEC_VAR_UNUSED_HANDLER, - ZEND_ASSIGN_SL_SPEC_VAR_CV_HANDLER, - ZEND_ASSIGN_SL_SPEC_UNUSED_CONST_HANDLER, - ZEND_ASSIGN_SL_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_SL_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_SL_SPEC_UNUSED_UNUSED_HANDLER, - ZEND_ASSIGN_SL_SPEC_UNUSED_CV_HANDLER, - ZEND_ASSIGN_SL_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_SL_SPEC_CV_UNUSED_HANDLER, - ZEND_ASSIGN_SL_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_ASSIGN_SR_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_SR_SPEC_VAR_UNUSED_HANDLER, - ZEND_ASSIGN_SR_SPEC_VAR_CV_HANDLER, - ZEND_ASSIGN_SR_SPEC_UNUSED_CONST_HANDLER, - ZEND_ASSIGN_SR_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_SR_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_SR_SPEC_UNUSED_UNUSED_HANDLER, - ZEND_ASSIGN_SR_SPEC_UNUSED_CV_HANDLER, - ZEND_ASSIGN_SR_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_SR_SPEC_CV_UNUSED_HANDLER, - ZEND_ASSIGN_SR_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_ASSIGN_CONCAT_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_CONCAT_SPEC_VAR_UNUSED_HANDLER, - ZEND_ASSIGN_CONCAT_SPEC_VAR_CV_HANDLER, - ZEND_ASSIGN_CONCAT_SPEC_UNUSED_CONST_HANDLER, - ZEND_ASSIGN_CONCAT_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_CONCAT_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_CONCAT_SPEC_UNUSED_UNUSED_HANDLER, - ZEND_ASSIGN_CONCAT_SPEC_UNUSED_CV_HANDLER, - ZEND_ASSIGN_CONCAT_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_CONCAT_SPEC_CV_UNUSED_HANDLER, - ZEND_ASSIGN_CONCAT_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_ASSIGN_BW_OR_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_OR_SPEC_VAR_UNUSED_HANDLER, - ZEND_ASSIGN_BW_OR_SPEC_VAR_CV_HANDLER, - ZEND_ASSIGN_BW_OR_SPEC_UNUSED_CONST_HANDLER, - ZEND_ASSIGN_BW_OR_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_OR_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_OR_SPEC_UNUSED_UNUSED_HANDLER, - ZEND_ASSIGN_BW_OR_SPEC_UNUSED_CV_HANDLER, - ZEND_ASSIGN_BW_OR_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_OR_SPEC_CV_UNUSED_HANDLER, - ZEND_ASSIGN_BW_OR_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_ASSIGN_BW_AND_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_AND_SPEC_VAR_UNUSED_HANDLER, - ZEND_ASSIGN_BW_AND_SPEC_VAR_CV_HANDLER, - ZEND_ASSIGN_BW_AND_SPEC_UNUSED_CONST_HANDLER, - ZEND_ASSIGN_BW_AND_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_AND_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_AND_SPEC_UNUSED_UNUSED_HANDLER, - ZEND_ASSIGN_BW_AND_SPEC_UNUSED_CV_HANDLER, - ZEND_ASSIGN_BW_AND_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_AND_SPEC_CV_UNUSED_HANDLER, - ZEND_ASSIGN_BW_AND_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_ASSIGN_BW_XOR_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_XOR_SPEC_VAR_UNUSED_HANDLER, - ZEND_ASSIGN_BW_XOR_SPEC_VAR_CV_HANDLER, - ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_CONST_HANDLER, - ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_UNUSED_HANDLER, - ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_CV_HANDLER, - ZEND_ASSIGN_BW_XOR_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_BW_XOR_SPEC_CV_UNUSED_HANDLER, - ZEND_ASSIGN_BW_XOR_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_PRE_INC_SPEC_VAR_HANDLER, - ZEND_PRE_INC_SPEC_VAR_HANDLER, - ZEND_PRE_INC_SPEC_VAR_HANDLER, - ZEND_PRE_INC_SPEC_VAR_HANDLER, - ZEND_PRE_INC_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_PRE_INC_SPEC_CV_HANDLER, - ZEND_PRE_INC_SPEC_CV_HANDLER, - ZEND_PRE_INC_SPEC_CV_HANDLER, - ZEND_PRE_INC_SPEC_CV_HANDLER, - ZEND_PRE_INC_SPEC_CV_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_NULL_HANDLER, - ZEND_PRE_DEC_SPEC_VAR_HANDLER, - ZEND_PRE_DEC_SPEC_VAR_HANDLER, - ZEND_PRE_DEC_SPEC_VAR_HANDLER, - ZEND_PRE_DEC_SPEC_VAR_HANDLER, - ZEND_PRE_DEC_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_PRE_DEC_SPEC_CV_HANDLER, - ZEND_PRE_DEC_SPEC_CV_HANDLER, - ZEND_PRE_DEC_SPEC_CV_HANDLER, - ZEND_PRE_DEC_SPEC_CV_HANDLER, - ZEND_PRE_DEC_SPEC_CV_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_NULL_HANDLER, - ZEND_POST_INC_SPEC_VAR_HANDLER, - ZEND_POST_INC_SPEC_VAR_HANDLER, - ZEND_POST_INC_SPEC_VAR_HANDLER, - ZEND_POST_INC_SPEC_VAR_HANDLER, - ZEND_POST_INC_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_POST_INC_SPEC_CV_HANDLER, - ZEND_POST_INC_SPEC_CV_HANDLER, - ZEND_POST_INC_SPEC_CV_HANDLER, - ZEND_POST_INC_SPEC_CV_HANDLER, - ZEND_POST_INC_SPEC_CV_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_NULL_HANDLER, - ZEND_POST_DEC_SPEC_VAR_HANDLER, - ZEND_POST_DEC_SPEC_VAR_HANDLER, - ZEND_POST_DEC_SPEC_VAR_HANDLER, - ZEND_POST_DEC_SPEC_VAR_HANDLER, - ZEND_POST_DEC_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_POST_DEC_SPEC_CV_HANDLER, - ZEND_POST_DEC_SPEC_CV_HANDLER, - ZEND_POST_DEC_SPEC_CV_HANDLER, - ZEND_POST_DEC_SPEC_CV_HANDLER, - ZEND_POST_DEC_SPEC_CV_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_NULL_HANDLER, - ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER, - ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ASSIGN_SPEC_VAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ASSIGN_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_SPEC_CV_TMP_HANDLER, - ZEND_ASSIGN_SPEC_CV_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ASSIGN_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER, - ZEND_ECHO_SPEC_CONST_HANDLER, - ZEND_ECHO_SPEC_CONST_HANDLER, - ZEND_ECHO_SPEC_CONST_HANDLER, - ZEND_ECHO_SPEC_CONST_HANDLER, - ZEND_ECHO_SPEC_CONST_HANDLER, - ZEND_ECHO_SPEC_TMPVAR_HANDLER, - ZEND_ECHO_SPEC_TMPVAR_HANDLER, - ZEND_ECHO_SPEC_TMPVAR_HANDLER, - ZEND_ECHO_SPEC_TMPVAR_HANDLER, - ZEND_ECHO_SPEC_TMPVAR_HANDLER, - ZEND_ECHO_SPEC_TMPVAR_HANDLER, - ZEND_ECHO_SPEC_TMPVAR_HANDLER, - ZEND_ECHO_SPEC_TMPVAR_HANDLER, - ZEND_ECHO_SPEC_TMPVAR_HANDLER, - ZEND_ECHO_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ECHO_SPEC_CV_HANDLER, - ZEND_ECHO_SPEC_CV_HANDLER, - ZEND_ECHO_SPEC_CV_HANDLER, - ZEND_ECHO_SPEC_CV_HANDLER, - ZEND_ECHO_SPEC_CV_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_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMP_SPEC_HANDLER, - ZEND_JMPZ_SPEC_CONST_HANDLER, - ZEND_JMPZ_SPEC_CONST_HANDLER, - ZEND_JMPZ_SPEC_CONST_HANDLER, - ZEND_JMPZ_SPEC_CONST_HANDLER, - ZEND_JMPZ_SPEC_CONST_HANDLER, - ZEND_JMPZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_JMPZ_SPEC_CV_HANDLER, - ZEND_JMPZ_SPEC_CV_HANDLER, - ZEND_JMPZ_SPEC_CV_HANDLER, - ZEND_JMPZ_SPEC_CV_HANDLER, - ZEND_JMPZ_SPEC_CV_HANDLER, - ZEND_JMPNZ_SPEC_CONST_HANDLER, - ZEND_JMPNZ_SPEC_CONST_HANDLER, - ZEND_JMPNZ_SPEC_CONST_HANDLER, - ZEND_JMPNZ_SPEC_CONST_HANDLER, - ZEND_JMPNZ_SPEC_CONST_HANDLER, - ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_JMPNZ_SPEC_CV_HANDLER, - ZEND_JMPNZ_SPEC_CV_HANDLER, - ZEND_JMPNZ_SPEC_CV_HANDLER, - ZEND_JMPNZ_SPEC_CV_HANDLER, - ZEND_JMPNZ_SPEC_CV_HANDLER, - ZEND_JMPZNZ_SPEC_CONST_HANDLER, - ZEND_JMPZNZ_SPEC_CONST_HANDLER, - ZEND_JMPZNZ_SPEC_CONST_HANDLER, - ZEND_JMPZNZ_SPEC_CONST_HANDLER, - ZEND_JMPZNZ_SPEC_CONST_HANDLER, - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_JMPZNZ_SPEC_CV_HANDLER, - ZEND_JMPZNZ_SPEC_CV_HANDLER, - ZEND_JMPZNZ_SPEC_CV_HANDLER, - ZEND_JMPZNZ_SPEC_CV_HANDLER, - ZEND_JMPZNZ_SPEC_CV_HANDLER, - ZEND_JMPZ_EX_SPEC_CONST_HANDLER, - ZEND_JMPZ_EX_SPEC_CONST_HANDLER, - ZEND_JMPZ_EX_SPEC_CONST_HANDLER, - ZEND_JMPZ_EX_SPEC_CONST_HANDLER, - ZEND_JMPZ_EX_SPEC_CONST_HANDLER, - ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_JMPZ_EX_SPEC_CV_HANDLER, - ZEND_JMPZ_EX_SPEC_CV_HANDLER, - ZEND_JMPZ_EX_SPEC_CV_HANDLER, - ZEND_JMPZ_EX_SPEC_CV_HANDLER, - ZEND_JMPZ_EX_SPEC_CV_HANDLER, - ZEND_JMPNZ_EX_SPEC_CONST_HANDLER, - ZEND_JMPNZ_EX_SPEC_CONST_HANDLER, - ZEND_JMPNZ_EX_SPEC_CONST_HANDLER, - ZEND_JMPNZ_EX_SPEC_CONST_HANDLER, - ZEND_JMPNZ_EX_SPEC_CONST_HANDLER, - ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_JMPNZ_EX_SPEC_CV_HANDLER, - ZEND_JMPNZ_EX_SPEC_CV_HANDLER, - ZEND_JMPNZ_EX_SPEC_CV_HANDLER, - ZEND_JMPNZ_EX_SPEC_CV_HANDLER, - ZEND_JMPNZ_EX_SPEC_CV_HANDLER, - ZEND_CASE_SPEC_CONST_CONST_HANDLER, - ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER, - ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CASE_SPEC_CONST_CV_HANDLER, - ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER, - ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CASE_SPEC_TMPVAR_CV_HANDLER, - ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER, - ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CASE_SPEC_TMPVAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CASE_SPEC_CV_CONST_HANDLER, - ZEND_CASE_SPEC_CV_TMPVAR_HANDLER, - ZEND_CASE_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CASE_SPEC_CV_CV_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_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_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_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_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_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_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_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_BOOL_SPEC_CONST_HANDLER, - ZEND_BOOL_SPEC_CONST_HANDLER, - ZEND_BOOL_SPEC_CONST_HANDLER, - ZEND_BOOL_SPEC_CONST_HANDLER, - ZEND_BOOL_SPEC_CONST_HANDLER, - ZEND_BOOL_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_BOOL_SPEC_CV_HANDLER, - ZEND_BOOL_SPEC_CV_HANDLER, - ZEND_BOOL_SPEC_CV_HANDLER, - ZEND_BOOL_SPEC_CV_HANDLER, - ZEND_BOOL_SPEC_CV_HANDLER, - ZEND_FAST_CONCAT_SPEC_CONST_CONST_HANDLER, - ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FAST_CONCAT_SPEC_CONST_CV_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FAST_CONCAT_SPEC_CV_CONST_HANDLER, - ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER, - ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FAST_CONCAT_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ROPE_INIT_SPEC_UNUSED_CONST_HANDLER, - ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ROPE_INIT_SPEC_UNUSED_CV_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_NULL_HANDLER, - ZEND_ROPE_ADD_SPEC_TMP_CONST_HANDLER, - ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER, - ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ROPE_ADD_SPEC_TMP_CV_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_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ROPE_END_SPEC_TMP_CONST_HANDLER, - ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER, - ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ROPE_END_SPEC_TMP_CV_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_BEGIN_SILENCE_SPEC_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_END_SILENCE_SPEC_TMP_HANDLER, - ZEND_END_SILENCE_SPEC_TMP_HANDLER, - ZEND_END_SILENCE_SPEC_TMP_HANDLER, - ZEND_END_SILENCE_SPEC_TMP_HANDLER, - ZEND_END_SILENCE_SPEC_TMP_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_DO_FCALL_SPEC_HANDLER, - ZEND_INIT_FCALL_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_FCALL_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_FCALL_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_FCALL_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_FCALL_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_RETURN_SPEC_CONST_HANDLER, - ZEND_RETURN_SPEC_CONST_HANDLER, - ZEND_RETURN_SPEC_CONST_HANDLER, - ZEND_RETURN_SPEC_CONST_HANDLER, - ZEND_RETURN_SPEC_CONST_HANDLER, - ZEND_RETURN_SPEC_TMP_HANDLER, - ZEND_RETURN_SPEC_TMP_HANDLER, - ZEND_RETURN_SPEC_TMP_HANDLER, - ZEND_RETURN_SPEC_TMP_HANDLER, - ZEND_RETURN_SPEC_TMP_HANDLER, - ZEND_RETURN_SPEC_VAR_HANDLER, - ZEND_RETURN_SPEC_VAR_HANDLER, - ZEND_RETURN_SPEC_VAR_HANDLER, - ZEND_RETURN_SPEC_VAR_HANDLER, - ZEND_RETURN_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_RETURN_SPEC_CV_HANDLER, - ZEND_RETURN_SPEC_CV_HANDLER, - ZEND_RETURN_SPEC_CV_HANDLER, - ZEND_RETURN_SPEC_CV_HANDLER, - ZEND_RETURN_SPEC_CV_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_SPEC_HANDLER, - ZEND_RECV_INIT_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_RECV_INIT_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_RECV_INIT_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_RECV_INIT_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_RECV_INIT_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SEND_VAL_SPEC_CONST_HANDLER, - ZEND_SEND_VAL_SPEC_CONST_HANDLER, - ZEND_SEND_VAL_SPEC_CONST_HANDLER, - ZEND_SEND_VAL_SPEC_CONST_HANDLER, - ZEND_SEND_VAL_SPEC_CONST_HANDLER, - ZEND_SEND_VAL_SPEC_TMP_HANDLER, - ZEND_SEND_VAL_SPEC_TMP_HANDLER, - ZEND_SEND_VAL_SPEC_TMP_HANDLER, - ZEND_SEND_VAL_SPEC_TMP_HANDLER, - ZEND_SEND_VAL_SPEC_TMP_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_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SEND_VAR_EX_SPEC_CV_HANDLER, - ZEND_SEND_VAR_EX_SPEC_CV_HANDLER, - ZEND_SEND_VAR_EX_SPEC_CV_HANDLER, - ZEND_SEND_VAR_EX_SPEC_CV_HANDLER, - ZEND_SEND_VAR_EX_SPEC_CV_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_NULL_HANDLER, - ZEND_SEND_REF_SPEC_VAR_HANDLER, - ZEND_SEND_REF_SPEC_VAR_HANDLER, - ZEND_SEND_REF_SPEC_VAR_HANDLER, - ZEND_SEND_REF_SPEC_VAR_HANDLER, - ZEND_SEND_REF_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SEND_REF_SPEC_CV_HANDLER, - ZEND_SEND_REF_SPEC_CV_HANDLER, - ZEND_SEND_REF_SPEC_CV_HANDLER, - ZEND_SEND_REF_SPEC_CV_HANDLER, - ZEND_SEND_REF_SPEC_CV_HANDLER, - ZEND_NEW_SPEC_CONST_HANDLER, - ZEND_NEW_SPEC_CONST_HANDLER, - ZEND_NEW_SPEC_CONST_HANDLER, - ZEND_NEW_SPEC_CONST_HANDLER, - ZEND_NEW_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NEW_SPEC_VAR_HANDLER, - ZEND_NEW_SPEC_VAR_HANDLER, - ZEND_NEW_SPEC_VAR_HANDLER, - ZEND_NEW_SPEC_VAR_HANDLER, - ZEND_NEW_SPEC_VAR_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_NULL_HANDLER, - ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_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_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FREE_SPEC_TMPVAR_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_NULL_HANDLER, - ZEND_INIT_ARRAY_SPEC_CONST_CONST_HANDLER, - ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER, - ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER, - ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_HANDLER, - ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDLER, - ZEND_INIT_ARRAY_SPEC_TMP_CONST_HANDLER, - ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER, - ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER, - ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HANDLER, - ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER, - ZEND_INIT_ARRAY_SPEC_VAR_CONST_HANDLER, - ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER, - ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER, - ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HANDLER, - ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER, - ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER, - ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER, - ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER, - ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDLER, - ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER, - ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER, - ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HANDLER, - ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER, - ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER, - ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_UNSET_VAR_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_UNSET_VAR_SPEC_TMPVAR_VAR_HANDLER, - ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_UNSET_VAR_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_UNSET_VAR_SPEC_TMPVAR_VAR_HANDLER, - ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER, - ZEND_UNSET_VAR_SPEC_CV_UNUSED_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER, - ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER, - ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER, - ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HANDLER, - ZEND_UNSET_DIM_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_UNSET_DIM_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER, - ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER, - ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER, - ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_UNSET_DIM_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER, - ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER, - ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER, - ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER, - ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER, - ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER, - ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER, - ZEND_FE_RESET_R_SPEC_CONST_HANDLER, - ZEND_FE_RESET_R_SPEC_CONST_HANDLER, - ZEND_FE_RESET_R_SPEC_CONST_HANDLER, - ZEND_FE_RESET_R_SPEC_CONST_HANDLER, - ZEND_FE_RESET_R_SPEC_CONST_HANDLER, - ZEND_FE_RESET_R_SPEC_TMP_HANDLER, - ZEND_FE_RESET_R_SPEC_TMP_HANDLER, - ZEND_FE_RESET_R_SPEC_TMP_HANDLER, - ZEND_FE_RESET_R_SPEC_TMP_HANDLER, - ZEND_FE_RESET_R_SPEC_TMP_HANDLER, - ZEND_FE_RESET_R_SPEC_VAR_HANDLER, - ZEND_FE_RESET_R_SPEC_VAR_HANDLER, - ZEND_FE_RESET_R_SPEC_VAR_HANDLER, - ZEND_FE_RESET_R_SPEC_VAR_HANDLER, - ZEND_FE_RESET_R_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FE_RESET_R_SPEC_CV_HANDLER, - ZEND_FE_RESET_R_SPEC_CV_HANDLER, - ZEND_FE_RESET_R_SPEC_CV_HANDLER, - ZEND_FE_RESET_R_SPEC_CV_HANDLER, - ZEND_FE_RESET_R_SPEC_CV_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_NULL_HANDLER, - ZEND_FE_FETCH_R_SPEC_VAR_HANDLER, - ZEND_FE_FETCH_R_SPEC_VAR_HANDLER, - ZEND_FE_FETCH_R_SPEC_VAR_HANDLER, - ZEND_FE_FETCH_R_SPEC_VAR_HANDLER, - ZEND_FE_FETCH_R_SPEC_VAR_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_NULL_HANDLER, - ZEND_EXIT_SPEC_CONST_HANDLER, - ZEND_EXIT_SPEC_CONST_HANDLER, - ZEND_EXIT_SPEC_CONST_HANDLER, - ZEND_EXIT_SPEC_CONST_HANDLER, - ZEND_EXIT_SPEC_CONST_HANDLER, - ZEND_EXIT_SPEC_TMPVAR_HANDLER, - ZEND_EXIT_SPEC_TMPVAR_HANDLER, - ZEND_EXIT_SPEC_TMPVAR_HANDLER, - ZEND_EXIT_SPEC_TMPVAR_HANDLER, - ZEND_EXIT_SPEC_TMPVAR_HANDLER, - ZEND_EXIT_SPEC_TMPVAR_HANDLER, - ZEND_EXIT_SPEC_TMPVAR_HANDLER, - ZEND_EXIT_SPEC_TMPVAR_HANDLER, - ZEND_EXIT_SPEC_TMPVAR_HANDLER, - ZEND_EXIT_SPEC_TMPVAR_HANDLER, - ZEND_EXIT_SPEC_UNUSED_HANDLER, - ZEND_EXIT_SPEC_UNUSED_HANDLER, - ZEND_EXIT_SPEC_UNUSED_HANDLER, - ZEND_EXIT_SPEC_UNUSED_HANDLER, - ZEND_EXIT_SPEC_UNUSED_HANDLER, - ZEND_EXIT_SPEC_CV_HANDLER, - ZEND_EXIT_SPEC_CV_HANDLER, - ZEND_EXIT_SPEC_CV_HANDLER, - ZEND_EXIT_SPEC_CV_HANDLER, - ZEND_EXIT_SPEC_CV_HANDLER, - ZEND_FETCH_R_SPEC_CONST_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_R_SPEC_CONST_VAR_HANDLER, - ZEND_FETCH_R_SPEC_CONST_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_R_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_R_SPEC_TMPVAR_VAR_HANDLER, - ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_R_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_R_SPEC_TMPVAR_VAR_HANDLER, - ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_R_SPEC_CV_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_R_SPEC_CV_VAR_HANDLER, - ZEND_FETCH_R_SPEC_CV_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER, - 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_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_NULL_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_VAR_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, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER, - ZEND_FETCH_W_SPEC_CONST_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_W_SPEC_CONST_VAR_HANDLER, - ZEND_FETCH_W_SPEC_CONST_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_W_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_W_SPEC_TMPVAR_VAR_HANDLER, - ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_W_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_W_SPEC_TMPVAR_VAR_HANDLER, - ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_W_SPEC_CV_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_W_SPEC_CV_VAR_HANDLER, - ZEND_FETCH_W_SPEC_CV_UNUSED_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER, - ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER, - ZEND_FETCH_DIM_W_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER, - ZEND_FETCH_RW_SPEC_CONST_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_RW_SPEC_CONST_VAR_HANDLER, - ZEND_FETCH_RW_SPEC_CONST_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_RW_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_RW_SPEC_TMPVAR_VAR_HANDLER, - ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_RW_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_RW_SPEC_TMPVAR_VAR_HANDLER, - ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_RW_SPEC_CV_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_RW_SPEC_CV_VAR_HANDLER, - ZEND_FETCH_RW_SPEC_CV_UNUSED_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER, - ZEND_FETCH_IS_SPEC_CONST_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_IS_SPEC_CONST_VAR_HANDLER, - ZEND_FETCH_IS_SPEC_CONST_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_IS_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_IS_SPEC_TMPVAR_VAR_HANDLER, - ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_IS_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_IS_SPEC_TMPVAR_VAR_HANDLER, - ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_IS_SPEC_CV_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_IS_SPEC_CV_VAR_HANDLER, - ZEND_FETCH_IS_SPEC_CV_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CONST_CV_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_CONST_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_CONST_VAR_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_VAR_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_VAR_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_CV_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_CV_VAR_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER, - ZEND_FETCH_UNSET_SPEC_CONST_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_UNSET_SPEC_CONST_VAR_HANDLER, - ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_UNSET_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_UNSET_SPEC_TMPVAR_VAR_HANDLER, - ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_UNSET_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_UNSET_SPEC_TMPVAR_VAR_HANDLER, - ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_UNSET_SPEC_CV_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_UNSET_SPEC_CV_VAR_HANDLER, - ZEND_FETCH_UNSET_SPEC_CV_UNUSED_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER, - 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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_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_FETCH_LIST_SPEC_CV_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_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_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_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_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_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_STMT_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_FCALL_END_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_EXT_NOP_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_HANDLER, - ZEND_TICKS_SPEC_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_NULL_HANDLER, - ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_NO_REF_SPEC_VAR_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CATCH_SPEC_CONST_CV_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_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_THROW_SPEC_CONST_HANDLER, - ZEND_THROW_SPEC_CONST_HANDLER, - ZEND_THROW_SPEC_CONST_HANDLER, - ZEND_THROW_SPEC_CONST_HANDLER, - ZEND_THROW_SPEC_CONST_HANDLER, - ZEND_THROW_SPEC_TMP_HANDLER, - ZEND_THROW_SPEC_TMP_HANDLER, - ZEND_THROW_SPEC_TMP_HANDLER, - ZEND_THROW_SPEC_TMP_HANDLER, - ZEND_THROW_SPEC_TMP_HANDLER, - ZEND_THROW_SPEC_VAR_HANDLER, - ZEND_THROW_SPEC_VAR_HANDLER, - ZEND_THROW_SPEC_VAR_HANDLER, - ZEND_THROW_SPEC_VAR_HANDLER, - ZEND_THROW_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_THROW_SPEC_CV_HANDLER, - ZEND_THROW_SPEC_CV_HANDLER, - ZEND_THROW_SPEC_CV_HANDLER, - ZEND_THROW_SPEC_CV_HANDLER, - ZEND_THROW_SPEC_CV_HANDLER, - ZEND_FETCH_CLASS_SPEC_CONST_HANDLER, - ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER, - ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER, - ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER, - ZEND_FETCH_CLASS_SPEC_CV_HANDLER, - ZEND_FETCH_CLASS_SPEC_CONST_HANDLER, - ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER, - ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER, - ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER, - ZEND_FETCH_CLASS_SPEC_CV_HANDLER, - ZEND_FETCH_CLASS_SPEC_CONST_HANDLER, - ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER, - ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER, - ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER, - ZEND_FETCH_CLASS_SPEC_CV_HANDLER, - ZEND_FETCH_CLASS_SPEC_CONST_HANDLER, - ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER, - ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER, - ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER, - ZEND_FETCH_CLASS_SPEC_CV_HANDLER, - ZEND_FETCH_CLASS_SPEC_CONST_HANDLER, - ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER, - ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER, - ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER, - ZEND_FETCH_CLASS_SPEC_CV_HANDLER, - ZEND_CLONE_SPEC_CONST_HANDLER, - ZEND_CLONE_SPEC_CONST_HANDLER, - ZEND_CLONE_SPEC_CONST_HANDLER, - ZEND_CLONE_SPEC_CONST_HANDLER, - ZEND_CLONE_SPEC_CONST_HANDLER, - ZEND_CLONE_SPEC_TMPVAR_HANDLER, - ZEND_CLONE_SPEC_TMPVAR_HANDLER, - ZEND_CLONE_SPEC_TMPVAR_HANDLER, - ZEND_CLONE_SPEC_TMPVAR_HANDLER, - ZEND_CLONE_SPEC_TMPVAR_HANDLER, - ZEND_CLONE_SPEC_TMPVAR_HANDLER, - ZEND_CLONE_SPEC_TMPVAR_HANDLER, - ZEND_CLONE_SPEC_TMPVAR_HANDLER, - ZEND_CLONE_SPEC_TMPVAR_HANDLER, - ZEND_CLONE_SPEC_TMPVAR_HANDLER, - ZEND_CLONE_SPEC_UNUSED_HANDLER, - ZEND_CLONE_SPEC_UNUSED_HANDLER, - ZEND_CLONE_SPEC_UNUSED_HANDLER, - ZEND_CLONE_SPEC_UNUSED_HANDLER, - ZEND_CLONE_SPEC_UNUSED_HANDLER, - ZEND_CLONE_SPEC_CV_HANDLER, - ZEND_CLONE_SPEC_CV_HANDLER, - ZEND_CLONE_SPEC_CV_HANDLER, - ZEND_CLONE_SPEC_CV_HANDLER, - ZEND_CLONE_SPEC_CV_HANDLER, - ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER, - ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER, - ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER, - ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER, - ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER, - ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER, - ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER, - ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER, - ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER, - ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER, - ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER, - ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER, - ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER, - ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER, - ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_RETURN_BY_REF_SPEC_CV_HANDLER, - ZEND_RETURN_BY_REF_SPEC_CV_HANDLER, - ZEND_RETURN_BY_REF_SPEC_CV_HANDLER, - ZEND_RETURN_BY_REF_SPEC_CV_HANDLER, - ZEND_RETURN_BY_REF_SPEC_CV_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CONST_CV_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_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_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_VAR_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_VAR_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_VAR_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_VAR_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CV_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER, - ZEND_SEND_VAL_EX_SPEC_CONST_HANDLER, - ZEND_SEND_VAL_EX_SPEC_CONST_HANDLER, - ZEND_SEND_VAL_EX_SPEC_CONST_HANDLER, - ZEND_SEND_VAL_EX_SPEC_CONST_HANDLER, - ZEND_SEND_VAL_EX_SPEC_CONST_HANDLER, - ZEND_SEND_VAL_EX_SPEC_TMP_HANDLER, - ZEND_SEND_VAL_EX_SPEC_TMP_HANDLER, - ZEND_SEND_VAL_EX_SPEC_TMP_HANDLER, - ZEND_SEND_VAL_EX_SPEC_TMP_HANDLER, - ZEND_SEND_VAL_EX_SPEC_TMP_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_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SEND_VAR_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SEND_VAR_SPEC_CV_HANDLER, - ZEND_SEND_VAR_SPEC_CV_HANDLER, - ZEND_SEND_VAR_SPEC_CV_HANDLER, - ZEND_SEND_VAR_SPEC_CV_HANDLER, - ZEND_SEND_VAR_SPEC_CV_HANDLER, - ZEND_INIT_USER_CALL_SPEC_CONST_CONST_HANDLER, - ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_USER_CALL_SPEC_CONST_CV_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_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_HANDLER, - ZEND_SEND_ARRAY_SPEC_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_NULL_HANDLER, - ZEND_SEND_USER_SPEC_VAR_HANDLER, - ZEND_SEND_USER_SPEC_VAR_HANDLER, - ZEND_SEND_USER_SPEC_VAR_HANDLER, - ZEND_SEND_USER_SPEC_VAR_HANDLER, - ZEND_SEND_USER_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SEND_USER_SPEC_CV_HANDLER, - ZEND_SEND_USER_SPEC_CV_HANDLER, - ZEND_SEND_USER_SPEC_CV_HANDLER, - ZEND_SEND_USER_SPEC_CV_HANDLER, - ZEND_SEND_USER_SPEC_CV_HANDLER, - ZEND_STRLEN_SPEC_CONST_HANDLER, - ZEND_STRLEN_SPEC_CONST_HANDLER, - ZEND_STRLEN_SPEC_CONST_HANDLER, - ZEND_STRLEN_SPEC_CONST_HANDLER, - ZEND_STRLEN_SPEC_CONST_HANDLER, - ZEND_STRLEN_SPEC_TMPVAR_HANDLER, - ZEND_STRLEN_SPEC_TMPVAR_HANDLER, - ZEND_STRLEN_SPEC_TMPVAR_HANDLER, - ZEND_STRLEN_SPEC_TMPVAR_HANDLER, - ZEND_STRLEN_SPEC_TMPVAR_HANDLER, - ZEND_STRLEN_SPEC_TMPVAR_HANDLER, - ZEND_STRLEN_SPEC_TMPVAR_HANDLER, - ZEND_STRLEN_SPEC_TMPVAR_HANDLER, - ZEND_STRLEN_SPEC_TMPVAR_HANDLER, - ZEND_STRLEN_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_STRLEN_SPEC_CV_HANDLER, - ZEND_STRLEN_SPEC_CV_HANDLER, - ZEND_STRLEN_SPEC_CV_HANDLER, - ZEND_STRLEN_SPEC_CV_HANDLER, - ZEND_STRLEN_SPEC_CV_HANDLER, - ZEND_DEFINED_SPEC_CONST_HANDLER, - ZEND_DEFINED_SPEC_CONST_HANDLER, - ZEND_DEFINED_SPEC_CONST_HANDLER, - ZEND_DEFINED_SPEC_CONST_HANDLER, - ZEND_DEFINED_SPEC_CONST_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_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_TYPE_CHECK_SPEC_CONST_HANDLER, - ZEND_TYPE_CHECK_SPEC_CONST_HANDLER, - ZEND_TYPE_CHECK_SPEC_CONST_HANDLER, - ZEND_TYPE_CHECK_SPEC_CONST_HANDLER, - ZEND_TYPE_CHECK_SPEC_CONST_HANDLER, - ZEND_TYPE_CHECK_SPEC_TMP_HANDLER, - ZEND_TYPE_CHECK_SPEC_TMP_HANDLER, - ZEND_TYPE_CHECK_SPEC_TMP_HANDLER, - ZEND_TYPE_CHECK_SPEC_TMP_HANDLER, - ZEND_TYPE_CHECK_SPEC_TMP_HANDLER, - ZEND_TYPE_CHECK_SPEC_VAR_HANDLER, - ZEND_TYPE_CHECK_SPEC_VAR_HANDLER, - ZEND_TYPE_CHECK_SPEC_VAR_HANDLER, - ZEND_TYPE_CHECK_SPEC_VAR_HANDLER, - ZEND_TYPE_CHECK_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_TYPE_CHECK_SPEC_CV_HANDLER, - ZEND_TYPE_CHECK_SPEC_CV_HANDLER, - ZEND_TYPE_CHECK_SPEC_CV_HANDLER, - ZEND_TYPE_CHECK_SPEC_CV_HANDLER, - ZEND_TYPE_CHECK_SPEC_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FE_RESET_RW_SPEC_CONST_HANDLER, - ZEND_FE_RESET_RW_SPEC_CONST_HANDLER, - ZEND_FE_RESET_RW_SPEC_CONST_HANDLER, - ZEND_FE_RESET_RW_SPEC_CONST_HANDLER, - ZEND_FE_RESET_RW_SPEC_CONST_HANDLER, - ZEND_FE_RESET_RW_SPEC_TMP_HANDLER, - ZEND_FE_RESET_RW_SPEC_TMP_HANDLER, - ZEND_FE_RESET_RW_SPEC_TMP_HANDLER, - ZEND_FE_RESET_RW_SPEC_TMP_HANDLER, - ZEND_FE_RESET_RW_SPEC_TMP_HANDLER, - ZEND_FE_RESET_RW_SPEC_VAR_HANDLER, - ZEND_FE_RESET_RW_SPEC_VAR_HANDLER, - ZEND_FE_RESET_RW_SPEC_VAR_HANDLER, - ZEND_FE_RESET_RW_SPEC_VAR_HANDLER, - ZEND_FE_RESET_RW_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FE_RESET_RW_SPEC_CV_HANDLER, - ZEND_FE_RESET_RW_SPEC_CV_HANDLER, - ZEND_FE_RESET_RW_SPEC_CV_HANDLER, - ZEND_FE_RESET_RW_SPEC_CV_HANDLER, - ZEND_FE_RESET_RW_SPEC_CV_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_NULL_HANDLER, - ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER, - ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER, - ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER, - ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER, - ZEND_FE_FETCH_RW_SPEC_VAR_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FE_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FE_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FE_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FE_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FE_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FE_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FE_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FE_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FE_FREE_SPEC_TMPVAR_HANDLER, - ZEND_FE_FREE_SPEC_TMPVAR_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_NULL_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_ICALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_UCALL_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, - ZEND_DO_FCALL_BY_NAME_SPEC_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_NULL_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_VAR_CV_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_CV_CONST_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_PRE_DEC_OBJ_SPEC_VAR_CONST_HANDLER, - ZEND_PRE_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER, - ZEND_PRE_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_PRE_DEC_OBJ_SPEC_VAR_CV_HANDLER, - ZEND_PRE_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER, - ZEND_PRE_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_PRE_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_PRE_DEC_OBJ_SPEC_UNUSED_CV_HANDLER, - ZEND_PRE_DEC_OBJ_SPEC_CV_CONST_HANDLER, - ZEND_PRE_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_PRE_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_PRE_DEC_OBJ_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_POST_INC_OBJ_SPEC_VAR_CONST_HANDLER, - ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER, - ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_POST_INC_OBJ_SPEC_VAR_CV_HANDLER, - ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER, - ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_HANDLER, - ZEND_POST_INC_OBJ_SPEC_CV_CONST_HANDLER, - ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_POST_INC_OBJ_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_POST_DEC_OBJ_SPEC_VAR_CONST_HANDLER, - ZEND_POST_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER, - ZEND_POST_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_POST_DEC_OBJ_SPEC_VAR_CV_HANDLER, - ZEND_POST_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER, - ZEND_POST_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_POST_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_POST_DEC_OBJ_SPEC_UNUSED_CV_HANDLER, - ZEND_POST_DEC_OBJ_SPEC_CV_CONST_HANDLER, - ZEND_POST_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_POST_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_POST_DEC_OBJ_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_CV_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_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_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_YIELD_FROM_SPEC_CONST_HANDLER, - ZEND_YIELD_FROM_SPEC_CONST_HANDLER, - ZEND_YIELD_FROM_SPEC_CONST_HANDLER, - ZEND_YIELD_FROM_SPEC_CONST_HANDLER, - ZEND_YIELD_FROM_SPEC_CONST_HANDLER, - ZEND_YIELD_FROM_SPEC_TMP_HANDLER, - ZEND_YIELD_FROM_SPEC_TMP_HANDLER, - ZEND_YIELD_FROM_SPEC_TMP_HANDLER, - ZEND_YIELD_FROM_SPEC_TMP_HANDLER, - ZEND_YIELD_FROM_SPEC_TMP_HANDLER, - ZEND_YIELD_FROM_SPEC_VAR_HANDLER, - ZEND_YIELD_FROM_SPEC_VAR_HANDLER, - ZEND_YIELD_FROM_SPEC_VAR_HANDLER, - ZEND_YIELD_FROM_SPEC_VAR_HANDLER, - ZEND_YIELD_FROM_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_YIELD_FROM_SPEC_CV_HANDLER, - ZEND_YIELD_FROM_SPEC_CV_HANDLER, - ZEND_YIELD_FROM_SPEC_CV_HANDLER, - ZEND_YIELD_FROM_SPEC_CV_HANDLER, - ZEND_YIELD_FROM_SPEC_CV_HANDLER, - ZEND_DECLARE_CONST_SPEC_CONST_CONST_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_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ADD_INTERFACE_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ADD_INTERFACE_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ADD_INTERFACE_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ADD_INTERFACE_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ADD_INTERFACE_SPEC_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER, - ZEND_VERIFY_ABSTRACT_CLASS_SPEC_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_NULL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_USER_OPCODE_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_ASSERT_CHECK_SPEC_HANDLER, - ZEND_JMP_SET_SPEC_CONST_HANDLER, - ZEND_JMP_SET_SPEC_CONST_HANDLER, - ZEND_JMP_SET_SPEC_CONST_HANDLER, - ZEND_JMP_SET_SPEC_CONST_HANDLER, - ZEND_JMP_SET_SPEC_CONST_HANDLER, - ZEND_JMP_SET_SPEC_TMP_HANDLER, - ZEND_JMP_SET_SPEC_TMP_HANDLER, - ZEND_JMP_SET_SPEC_TMP_HANDLER, - ZEND_JMP_SET_SPEC_TMP_HANDLER, - ZEND_JMP_SET_SPEC_TMP_HANDLER, - ZEND_JMP_SET_SPEC_VAR_HANDLER, - ZEND_JMP_SET_SPEC_VAR_HANDLER, - ZEND_JMP_SET_SPEC_VAR_HANDLER, - ZEND_JMP_SET_SPEC_VAR_HANDLER, - ZEND_JMP_SET_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_JMP_SET_SPEC_CV_HANDLER, - ZEND_JMP_SET_SPEC_CV_HANDLER, - ZEND_JMP_SET_SPEC_CV_HANDLER, - ZEND_JMP_SET_SPEC_CV_HANDLER, - ZEND_JMP_SET_SPEC_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_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_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_ADD_TRAIT_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_HANDLER, - ZEND_BIND_TRAITS_SPEC_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SEPARATE_SPEC_VAR_UNUSED_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, - ZEND_YIELD_SPEC_CONST_CONST_HANDLER, - ZEND_YIELD_SPEC_CONST_TMP_HANDLER, - ZEND_YIELD_SPEC_CONST_VAR_HANDLER, - ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER, - ZEND_YIELD_SPEC_CONST_CV_HANDLER, - ZEND_YIELD_SPEC_TMP_CONST_HANDLER, - ZEND_YIELD_SPEC_TMP_TMP_HANDLER, - ZEND_YIELD_SPEC_TMP_VAR_HANDLER, - ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER, - ZEND_YIELD_SPEC_TMP_CV_HANDLER, - ZEND_YIELD_SPEC_VAR_CONST_HANDLER, - ZEND_YIELD_SPEC_VAR_TMP_HANDLER, - ZEND_YIELD_SPEC_VAR_VAR_HANDLER, - ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER, - ZEND_YIELD_SPEC_VAR_CV_HANDLER, - ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER, - ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER, - ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER, - ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER, - ZEND_YIELD_SPEC_UNUSED_CV_HANDLER, - ZEND_YIELD_SPEC_CV_CONST_HANDLER, - ZEND_YIELD_SPEC_CV_TMP_HANDLER, - ZEND_YIELD_SPEC_CV_VAR_HANDLER, - ZEND_YIELD_SPEC_CV_UNUSED_HANDLER, - ZEND_YIELD_SPEC_CV_CV_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_CONST_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_CONST_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_CONST_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_CONST_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_CONST_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_TMP_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_TMP_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_TMP_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_TMP_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_TMP_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_VAR_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_VAR_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_VAR_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_VAR_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_CV_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_CV_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_CV_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_CV_HANDLER, - ZEND_GENERATOR_RETURN_SPEC_CV_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_CALL_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_FAST_RET_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_RECV_VARIADIC_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_SEND_UNPACK_SPEC_HANDLER, - ZEND_POW_SPEC_CONST_CONST_HANDLER, - ZEND_POW_SPEC_CONST_TMPVAR_HANDLER, - ZEND_POW_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_POW_SPEC_CONST_CV_HANDLER, - ZEND_POW_SPEC_TMPVAR_CONST_HANDLER, - ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_POW_SPEC_TMPVAR_CV_HANDLER, - ZEND_POW_SPEC_TMPVAR_CONST_HANDLER, - ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_POW_SPEC_TMPVAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_POW_SPEC_CV_CONST_HANDLER, - ZEND_POW_SPEC_CV_TMPVAR_HANDLER, - ZEND_POW_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_POW_SPEC_CV_CV_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_NULL_HANDLER, - ZEND_ASSIGN_POW_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_POW_SPEC_VAR_UNUSED_HANDLER, - ZEND_ASSIGN_POW_SPEC_VAR_CV_HANDLER, - ZEND_ASSIGN_POW_SPEC_UNUSED_CONST_HANDLER, - ZEND_ASSIGN_POW_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_POW_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_POW_SPEC_UNUSED_UNUSED_HANDLER, - ZEND_ASSIGN_POW_SPEC_UNUSED_CV_HANDLER, - ZEND_ASSIGN_POW_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_POW_SPEC_CV_UNUSED_HANDLER, - ZEND_ASSIGN_POW_SPEC_CV_CV_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_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_COALESCE_SPEC_CONST_HANDLER, - ZEND_COALESCE_SPEC_CONST_HANDLER, - ZEND_COALESCE_SPEC_CONST_HANDLER, - ZEND_COALESCE_SPEC_CONST_HANDLER, - ZEND_COALESCE_SPEC_CONST_HANDLER, - ZEND_COALESCE_SPEC_TMP_HANDLER, - ZEND_COALESCE_SPEC_TMP_HANDLER, - ZEND_COALESCE_SPEC_TMP_HANDLER, - ZEND_COALESCE_SPEC_TMP_HANDLER, - ZEND_COALESCE_SPEC_TMP_HANDLER, - ZEND_COALESCE_SPEC_VAR_HANDLER, - ZEND_COALESCE_SPEC_VAR_HANDLER, - ZEND_COALESCE_SPEC_VAR_HANDLER, - ZEND_COALESCE_SPEC_VAR_HANDLER, - ZEND_COALESCE_SPEC_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_COALESCE_SPEC_CV_HANDLER, - ZEND_COALESCE_SPEC_CV_HANDLER, - ZEND_COALESCE_SPEC_CV_HANDLER, - ZEND_COALESCE_SPEC_CV_HANDLER, - ZEND_COALESCE_SPEC_CV_HANDLER, - ZEND_SPACESHIP_SPEC_CONST_CONST_HANDLER, - ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER, - ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SPACESHIP_SPEC_CONST_CV_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SPACESHIP_SPEC_CV_CONST_HANDLER, - ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER, - ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_SPACESHIP_SPEC_CV_CV_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_HANDLER, - ZEND_NULL_HANDLER - }; - zend_opcode_handlers = labels; + static const void *labels[] = { + ZEND_NOP_SPEC_HANDLER, + ZEND_ADD_SPEC_CONST_CONST_HANDLER, + ZEND_ADD_SPEC_CONST_TMPVAR_HANDLER, + ZEND_ADD_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ADD_SPEC_CONST_CV_HANDLER, + ZEND_ADD_SPEC_TMPVAR_CONST_HANDLER, + ZEND_ADD_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_ADD_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ADD_SPEC_TMPVAR_CV_HANDLER, + ZEND_ADD_SPEC_TMPVAR_CONST_HANDLER, + ZEND_ADD_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_ADD_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ADD_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ADD_SPEC_CV_CONST_HANDLER, + ZEND_ADD_SPEC_CV_TMPVAR_HANDLER, + ZEND_ADD_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ADD_SPEC_CV_CV_HANDLER, + ZEND_SUB_SPEC_CONST_CONST_HANDLER, + ZEND_SUB_SPEC_CONST_TMPVAR_HANDLER, + ZEND_SUB_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_SPEC_CONST_CV_HANDLER, + ZEND_SUB_SPEC_TMPVAR_CONST_HANDLER, + ZEND_SUB_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_SUB_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_SPEC_TMPVAR_CV_HANDLER, + ZEND_SUB_SPEC_TMPVAR_CONST_HANDLER, + ZEND_SUB_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_SUB_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_SPEC_CV_CONST_HANDLER, + ZEND_SUB_SPEC_CV_TMPVAR_HANDLER, + ZEND_SUB_SPEC_CV_TMPVAR_HANDLER, + 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_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_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, + ZEND_NULL_HANDLER, + ZEND_MUL_SPEC_CV_CONST_HANDLER, + ZEND_MUL_SPEC_CV_TMPVAR_HANDLER, + ZEND_MUL_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_MUL_SPEC_CV_CV_HANDLER, + ZEND_DIV_SPEC_CONST_CONST_HANDLER, + ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER, + ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_DIV_SPEC_CONST_CV_HANDLER, + ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER, + ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_DIV_SPEC_TMPVAR_CV_HANDLER, + ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER, + ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_DIV_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_DIV_SPEC_CV_CONST_HANDLER, + ZEND_DIV_SPEC_CV_TMPVAR_HANDLER, + ZEND_DIV_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_DIV_SPEC_CV_CV_HANDLER, + ZEND_MOD_SPEC_CONST_CONST_HANDLER, + ZEND_MOD_SPEC_CONST_TMPVAR_HANDLER, + ZEND_MOD_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_MOD_SPEC_CONST_CV_HANDLER, + ZEND_MOD_SPEC_TMPVAR_CONST_HANDLER, + ZEND_MOD_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_MOD_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_MOD_SPEC_TMPVAR_CV_HANDLER, + ZEND_MOD_SPEC_TMPVAR_CONST_HANDLER, + ZEND_MOD_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_MOD_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_MOD_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_MOD_SPEC_CV_CONST_HANDLER, + ZEND_MOD_SPEC_CV_TMPVAR_HANDLER, + ZEND_MOD_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_MOD_SPEC_CV_CV_HANDLER, + ZEND_SL_SPEC_CONST_CONST_HANDLER, + ZEND_SL_SPEC_CONST_TMPVAR_HANDLER, + ZEND_SL_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SL_SPEC_CONST_CV_HANDLER, + ZEND_SL_SPEC_TMPVAR_CONST_HANDLER, + ZEND_SL_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_SL_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SL_SPEC_TMPVAR_CV_HANDLER, + ZEND_SL_SPEC_TMPVAR_CONST_HANDLER, + ZEND_SL_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_SL_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SL_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SL_SPEC_CV_CONST_HANDLER, + ZEND_SL_SPEC_CV_TMPVAR_HANDLER, + ZEND_SL_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SL_SPEC_CV_CV_HANDLER, + ZEND_SR_SPEC_CONST_CONST_HANDLER, + ZEND_SR_SPEC_CONST_TMPVAR_HANDLER, + ZEND_SR_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SR_SPEC_CONST_CV_HANDLER, + ZEND_SR_SPEC_TMPVAR_CONST_HANDLER, + ZEND_SR_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_SR_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SR_SPEC_TMPVAR_CV_HANDLER, + ZEND_SR_SPEC_TMPVAR_CONST_HANDLER, + ZEND_SR_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_SR_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SR_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SR_SPEC_CV_CONST_HANDLER, + ZEND_SR_SPEC_CV_TMPVAR_HANDLER, + ZEND_SR_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SR_SPEC_CV_CV_HANDLER, + ZEND_CONCAT_SPEC_CONST_CONST_HANDLER, + ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER, + ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_CONCAT_SPEC_CONST_CV_HANDLER, + ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER, + ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER, + ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER, + ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_CONCAT_SPEC_CV_CONST_HANDLER, + ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER, + ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER, + 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_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_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, + ZEND_NULL_HANDLER, + ZEND_BW_OR_SPEC_CV_CONST_HANDLER, + ZEND_BW_OR_SPEC_CV_TMPVAR_HANDLER, + ZEND_BW_OR_SPEC_CV_TMPVAR_HANDLER, + 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_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_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, + ZEND_NULL_HANDLER, + ZEND_BW_AND_SPEC_CV_CONST_HANDLER, + ZEND_BW_AND_SPEC_CV_TMPVAR_HANDLER, + ZEND_BW_AND_SPEC_CV_TMPVAR_HANDLER, + 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_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_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, + ZEND_NULL_HANDLER, + ZEND_BW_XOR_SPEC_CV_CONST_HANDLER, + ZEND_BW_XOR_SPEC_CV_TMPVAR_HANDLER, + ZEND_BW_XOR_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_BW_XOR_SPEC_CV_CV_HANDLER, + ZEND_BW_NOT_SPEC_CONST_HANDLER, + ZEND_BW_NOT_SPEC_TMPVAR_HANDLER, + ZEND_BW_NOT_SPEC_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_BW_NOT_SPEC_CV_HANDLER, + ZEND_BOOL_NOT_SPEC_CONST_HANDLER, + ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER, + ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER, + 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_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_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, + ZEND_NULL_HANDLER, + ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER, + ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER, + ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER, + 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_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_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, + ZEND_NULL_HANDLER, + ZEND_IS_IDENTICAL_SPEC_CV_CONST_HANDLER, + ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER, + ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER, + 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_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_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, + ZEND_NULL_HANDLER, + ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_HANDLER, + ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER, + ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER, + 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_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_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, + ZEND_NULL_HANDLER, + ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER, + ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER, + ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER, + 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_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_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, + ZEND_NULL_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLER, + ZEND_IS_SMALLER_SPEC_CONST_CONST_HANDLER, + ZEND_IS_SMALLER_SPEC_CONST_TMPVAR_HANDLER, + ZEND_IS_SMALLER_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_SPEC_CONST_CV_HANDLER, + ZEND_IS_SMALLER_SPEC_TMPVAR_CONST_HANDLER, + ZEND_IS_SMALLER_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_IS_SMALLER_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_SPEC_TMPVAR_CV_HANDLER, + ZEND_IS_SMALLER_SPEC_TMPVAR_CONST_HANDLER, + ZEND_IS_SMALLER_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_IS_SMALLER_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_SPEC_CV_CONST_HANDLER, + ZEND_IS_SMALLER_SPEC_CV_TMPVAR_HANDLER, + ZEND_IS_SMALLER_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_SPEC_CV_CV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVAR_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CONST_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CONST_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CONST_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMPVAR_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CV_HANDLER, + ZEND_CAST_SPEC_CONST_HANDLER, + ZEND_CAST_SPEC_TMP_HANDLER, + ZEND_CAST_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_CAST_SPEC_CV_HANDLER, + ZEND_QM_ASSIGN_SPEC_CONST_HANDLER, + ZEND_QM_ASSIGN_SPEC_TMP_HANDLER, + ZEND_QM_ASSIGN_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_QM_ASSIGN_SPEC_CV_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_NULL_HANDLER, + ZEND_ASSIGN_ADD_SPEC_VAR_CONST_HANDLER, + ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_ADD_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_ADD_SPEC_VAR_UNUSED_HANDLER, + ZEND_ASSIGN_ADD_SPEC_VAR_CV_HANDLER, + ZEND_ASSIGN_ADD_SPEC_UNUSED_CONST_HANDLER, + ZEND_ASSIGN_ADD_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_ADD_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_ADD_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_ASSIGN_ADD_SPEC_UNUSED_CV_HANDLER, + ZEND_ASSIGN_ADD_SPEC_CV_CONST_HANDLER, + ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_ADD_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_ADD_SPEC_CV_UNUSED_HANDLER, + ZEND_ASSIGN_ADD_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_ASSIGN_SUB_SPEC_VAR_CONST_HANDLER, + ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_SUB_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_SUB_SPEC_VAR_UNUSED_HANDLER, + ZEND_ASSIGN_SUB_SPEC_VAR_CV_HANDLER, + ZEND_ASSIGN_SUB_SPEC_UNUSED_CONST_HANDLER, + ZEND_ASSIGN_SUB_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_SUB_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_SUB_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_ASSIGN_SUB_SPEC_UNUSED_CV_HANDLER, + ZEND_ASSIGN_SUB_SPEC_CV_CONST_HANDLER, + ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_SUB_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_SUB_SPEC_CV_UNUSED_HANDLER, + ZEND_ASSIGN_SUB_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_ASSIGN_MUL_SPEC_VAR_CONST_HANDLER, + ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_MUL_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_MUL_SPEC_VAR_UNUSED_HANDLER, + ZEND_ASSIGN_MUL_SPEC_VAR_CV_HANDLER, + ZEND_ASSIGN_MUL_SPEC_UNUSED_CONST_HANDLER, + ZEND_ASSIGN_MUL_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_MUL_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_MUL_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_ASSIGN_MUL_SPEC_UNUSED_CV_HANDLER, + ZEND_ASSIGN_MUL_SPEC_CV_CONST_HANDLER, + ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_MUL_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_MUL_SPEC_CV_UNUSED_HANDLER, + ZEND_ASSIGN_MUL_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_ASSIGN_DIV_SPEC_VAR_CONST_HANDLER, + ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_DIV_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_DIV_SPEC_VAR_UNUSED_HANDLER, + ZEND_ASSIGN_DIV_SPEC_VAR_CV_HANDLER, + ZEND_ASSIGN_DIV_SPEC_UNUSED_CONST_HANDLER, + ZEND_ASSIGN_DIV_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_DIV_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_DIV_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_ASSIGN_DIV_SPEC_UNUSED_CV_HANDLER, + ZEND_ASSIGN_DIV_SPEC_CV_CONST_HANDLER, + ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_DIV_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_DIV_SPEC_CV_UNUSED_HANDLER, + ZEND_ASSIGN_DIV_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_ASSIGN_MOD_SPEC_VAR_CONST_HANDLER, + ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_MOD_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_MOD_SPEC_VAR_UNUSED_HANDLER, + ZEND_ASSIGN_MOD_SPEC_VAR_CV_HANDLER, + ZEND_ASSIGN_MOD_SPEC_UNUSED_CONST_HANDLER, + ZEND_ASSIGN_MOD_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_MOD_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_MOD_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_ASSIGN_MOD_SPEC_UNUSED_CV_HANDLER, + ZEND_ASSIGN_MOD_SPEC_CV_CONST_HANDLER, + ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_MOD_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_MOD_SPEC_CV_UNUSED_HANDLER, + ZEND_ASSIGN_MOD_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_ASSIGN_SL_SPEC_VAR_CONST_HANDLER, + ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_SL_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_SL_SPEC_VAR_UNUSED_HANDLER, + ZEND_ASSIGN_SL_SPEC_VAR_CV_HANDLER, + ZEND_ASSIGN_SL_SPEC_UNUSED_CONST_HANDLER, + ZEND_ASSIGN_SL_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_SL_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_SL_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_ASSIGN_SL_SPEC_UNUSED_CV_HANDLER, + ZEND_ASSIGN_SL_SPEC_CV_CONST_HANDLER, + ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_SL_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_SL_SPEC_CV_UNUSED_HANDLER, + ZEND_ASSIGN_SL_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_ASSIGN_SR_SPEC_VAR_CONST_HANDLER, + ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_SR_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_SR_SPEC_VAR_UNUSED_HANDLER, + ZEND_ASSIGN_SR_SPEC_VAR_CV_HANDLER, + ZEND_ASSIGN_SR_SPEC_UNUSED_CONST_HANDLER, + ZEND_ASSIGN_SR_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_SR_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_SR_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_ASSIGN_SR_SPEC_UNUSED_CV_HANDLER, + ZEND_ASSIGN_SR_SPEC_CV_CONST_HANDLER, + ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_SR_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_SR_SPEC_CV_UNUSED_HANDLER, + ZEND_ASSIGN_SR_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_ASSIGN_CONCAT_SPEC_VAR_CONST_HANDLER, + ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_CONCAT_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_CONCAT_SPEC_VAR_UNUSED_HANDLER, + ZEND_ASSIGN_CONCAT_SPEC_VAR_CV_HANDLER, + ZEND_ASSIGN_CONCAT_SPEC_UNUSED_CONST_HANDLER, + ZEND_ASSIGN_CONCAT_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_CONCAT_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_CONCAT_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_ASSIGN_CONCAT_SPEC_UNUSED_CV_HANDLER, + ZEND_ASSIGN_CONCAT_SPEC_CV_CONST_HANDLER, + ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_CONCAT_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_CONCAT_SPEC_CV_UNUSED_HANDLER, + ZEND_ASSIGN_CONCAT_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_ASSIGN_BW_OR_SPEC_VAR_CONST_HANDLER, + ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_OR_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_OR_SPEC_VAR_UNUSED_HANDLER, + ZEND_ASSIGN_BW_OR_SPEC_VAR_CV_HANDLER, + ZEND_ASSIGN_BW_OR_SPEC_UNUSED_CONST_HANDLER, + ZEND_ASSIGN_BW_OR_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_OR_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_OR_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_ASSIGN_BW_OR_SPEC_UNUSED_CV_HANDLER, + ZEND_ASSIGN_BW_OR_SPEC_CV_CONST_HANDLER, + ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_OR_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_OR_SPEC_CV_UNUSED_HANDLER, + ZEND_ASSIGN_BW_OR_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_ASSIGN_BW_AND_SPEC_VAR_CONST_HANDLER, + ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_AND_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_AND_SPEC_VAR_UNUSED_HANDLER, + ZEND_ASSIGN_BW_AND_SPEC_VAR_CV_HANDLER, + ZEND_ASSIGN_BW_AND_SPEC_UNUSED_CONST_HANDLER, + ZEND_ASSIGN_BW_AND_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_AND_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_AND_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_ASSIGN_BW_AND_SPEC_UNUSED_CV_HANDLER, + ZEND_ASSIGN_BW_AND_SPEC_CV_CONST_HANDLER, + ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_AND_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_AND_SPEC_CV_UNUSED_HANDLER, + ZEND_ASSIGN_BW_AND_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_ASSIGN_BW_XOR_SPEC_VAR_CONST_HANDLER, + ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_XOR_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_XOR_SPEC_VAR_UNUSED_HANDLER, + ZEND_ASSIGN_BW_XOR_SPEC_VAR_CV_HANDLER, + ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_CONST_HANDLER, + ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_CV_HANDLER, + ZEND_ASSIGN_BW_XOR_SPEC_CV_CONST_HANDLER, + ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_XOR_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_BW_XOR_SPEC_CV_UNUSED_HANDLER, + ZEND_ASSIGN_BW_XOR_SPEC_CV_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_INC_SPEC_VAR_RETVAL_UNUSED_HANDLER, + ZEND_PRE_INC_SPEC_VAR_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_INC_SPEC_CV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_INC_SPEC_CV_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_DEC_SPEC_VAR_RETVAL_UNUSED_HANDLER, + ZEND_PRE_DEC_SPEC_VAR_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_DEC_SPEC_CV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_DEC_SPEC_CV_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_INC_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_INC_SPEC_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_DEC_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_DEC_SPEC_CV_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_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_UNUSED_HANDLER, + ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_USED_HANDLER, + ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED_HANDLER, + ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_HANDLER, + ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED_HANDLER, + ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER, + ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_USED_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_NULL_HANDLER, + ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UNUSED_HANDLER, + ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_USED_HANDLER, + ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_HANDLER, + ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_HANDLER, + ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_HANDLER, + ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED_HANDLER, + ZEND_ASSIGN_SPEC_CV_CV_RETVAL_USED_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER, + ZEND_ECHO_SPEC_CONST_HANDLER, + ZEND_ECHO_SPEC_TMPVAR_HANDLER, + ZEND_ECHO_SPEC_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ECHO_SPEC_CV_HANDLER, + ZEND_JMP_SPEC_HANDLER, + ZEND_JMPZ_SPEC_CONST_HANDLER, + ZEND_JMPZ_SPEC_TMPVAR_HANDLER, + ZEND_JMPZ_SPEC_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_JMPZ_SPEC_CV_HANDLER, + ZEND_JMPNZ_SPEC_CONST_HANDLER, + ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, + ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_JMPNZ_SPEC_CV_HANDLER, + ZEND_JMPZNZ_SPEC_CONST_HANDLER, + ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, + ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_JMPZNZ_SPEC_CV_HANDLER, + ZEND_JMPZ_EX_SPEC_CONST_HANDLER, + ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, + ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_JMPZ_EX_SPEC_CV_HANDLER, + ZEND_JMPNZ_EX_SPEC_CONST_HANDLER, + ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER, + ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_JMPNZ_EX_SPEC_CV_HANDLER, + ZEND_CASE_SPEC_CONST_CONST_HANDLER, + ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER, + ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_CASE_SPEC_CONST_CV_HANDLER, + ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER, + ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_CASE_SPEC_TMPVAR_CV_HANDLER, + ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER, + ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_CASE_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_CASE_SPEC_CV_CONST_HANDLER, + ZEND_CASE_SPEC_CV_TMPVAR_HANDLER, + ZEND_CASE_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_CASE_SPEC_CV_CV_HANDLER, + ZEND_BOOL_SPEC_CONST_HANDLER, + ZEND_BOOL_SPEC_TMPVAR_HANDLER, + ZEND_BOOL_SPEC_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_BOOL_SPEC_CV_HANDLER, + ZEND_FAST_CONCAT_SPEC_CONST_CONST_HANDLER, + ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FAST_CONCAT_SPEC_CONST_CV_HANDLER, + ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER, + ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FAST_CONCAT_SPEC_CV_CONST_HANDLER, + ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER, + ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FAST_CONCAT_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ROPE_INIT_SPEC_UNUSED_CONST_HANDLER, + ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ROPE_INIT_SPEC_UNUSED_CV_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_NULL_HANDLER, + ZEND_ROPE_ADD_SPEC_TMP_CONST_HANDLER, + ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER, + ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ROPE_ADD_SPEC_TMP_CV_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_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ROPE_END_SPEC_TMP_CONST_HANDLER, + ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER, + ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ROPE_END_SPEC_TMP_CV_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_BEGIN_SILENCE_SPEC_HANDLER, + ZEND_NULL_HANDLER, + ZEND_END_SILENCE_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER, + ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER, + ZEND_INIT_FCALL_SPEC_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_RETURN_SPEC_CONST_HANDLER, + ZEND_RETURN_SPEC_TMP_HANDLER, + ZEND_RETURN_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_RETURN_SPEC_CV_HANDLER, + ZEND_RECV_SPEC_HANDLER, + ZEND_RECV_INIT_SPEC_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_VAL_SPEC_CONST_HANDLER, + ZEND_SEND_VAL_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER, + ZEND_SEND_VAR_EX_SPEC_VAR_QUICK_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_VAR_EX_SPEC_CV_HANDLER, + ZEND_SEND_VAR_EX_SPEC_CV_QUICK_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_REF_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_REF_SPEC_CV_HANDLER, + ZEND_NEW_SPEC_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NEW_SPEC_VAR_HANDLER, + ZEND_NEW_SPEC_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FREE_SPEC_TMPVAR_HANDLER, + ZEND_FREE_SPEC_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INIT_ARRAY_SPEC_CONST_CONST_HANDLER, + ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_HANDLER, + ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDLER, + ZEND_INIT_ARRAY_SPEC_TMP_CONST_HANDLER, + ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HANDLER, + ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER, + ZEND_INIT_ARRAY_SPEC_VAR_CONST_HANDLER, + ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HANDLER, + ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER, + ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER, + ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER, + ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDLER, + ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HANDLER, + ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER, + ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER, + ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER, + ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_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_UNSET_VAR_SPEC_CV_UNUSED_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER, + ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER, + ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER, + ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HANDLER, + ZEND_UNSET_DIM_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_UNSET_DIM_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER, + ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER, + ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER, + ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_DIM_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER, + ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER, + ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER, + ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER, + ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER, + ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER, + ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER, + ZEND_FE_RESET_R_SPEC_CONST_HANDLER, + ZEND_FE_RESET_R_SPEC_TMP_HANDLER, + ZEND_FE_RESET_R_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FE_RESET_R_SPEC_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FE_FETCH_R_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_EXIT_SPEC_CONST_HANDLER, + ZEND_EXIT_SPEC_TMPVAR_HANDLER, + ZEND_EXIT_SPEC_TMPVAR_HANDLER, + ZEND_EXIT_SPEC_UNUSED_HANDLER, + ZEND_EXIT_SPEC_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_R_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_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_FETCH_R_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER, + 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_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_NULL_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_VAR_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, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_W_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_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_FETCH_W_SPEC_CV_UNUSED_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER, + ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER, + ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER, + ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER, + ZEND_FETCH_DIM_W_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_RW_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_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_FETCH_RW_SPEC_CV_UNUSED_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER, + ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER, + ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER, + ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER, + ZEND_FETCH_DIM_RW_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_IS_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_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_FETCH_IS_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CONST_CV_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_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_FETCH_FUNC_ARG_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_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_FETCH_UNSET_SPEC_CV_UNUSED_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER, + ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER, + ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER, + 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_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_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_NULL_HANDLER, + ZEND_FETCH_LIST_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_NULL_HANDLER, + ZEND_FETCH_LIST_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_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_EXT_STMT_SPEC_HANDLER, + ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER, + ZEND_EXT_FCALL_END_SPEC_HANDLER, + ZEND_EXT_NOP_SPEC_HANDLER, + ZEND_TICKS_SPEC_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_CATCH_SPEC_CONST_CV_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_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_THROW_SPEC_CONST_HANDLER, + ZEND_THROW_SPEC_TMP_HANDLER, + ZEND_THROW_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_THROW_SPEC_CV_HANDLER, + ZEND_FETCH_CLASS_SPEC_CONST_HANDLER, + ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER, + ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER, + ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER, + ZEND_FETCH_CLASS_SPEC_CV_HANDLER, + ZEND_CLONE_SPEC_CONST_HANDLER, + ZEND_CLONE_SPEC_TMPVAR_HANDLER, + ZEND_CLONE_SPEC_TMPVAR_HANDLER, + ZEND_CLONE_SPEC_UNUSED_HANDLER, + ZEND_CLONE_SPEC_CV_HANDLER, + ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER, + ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER, + ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_RETURN_BY_REF_SPEC_CV_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CONST_CV_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_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_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_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_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CONST_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CV_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER, + ZEND_SEND_VAL_EX_SPEC_CONST_HANDLER, + ZEND_SEND_VAL_EX_SPEC_CONST_QUICK_HANDLER, + ZEND_SEND_VAL_EX_SPEC_TMP_HANDLER, + ZEND_SEND_VAL_EX_SPEC_TMP_QUICK_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_SEND_VAR_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_VAR_SPEC_CV_HANDLER, + ZEND_INIT_USER_CALL_SPEC_CONST_CONST_HANDLER, + ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER, + ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INIT_USER_CALL_SPEC_CONST_CV_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_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_ARRAY_SPEC_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_USER_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEND_USER_SPEC_CV_HANDLER, + ZEND_STRLEN_SPEC_CONST_HANDLER, + ZEND_STRLEN_SPEC_TMPVAR_HANDLER, + ZEND_STRLEN_SPEC_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_STRLEN_SPEC_CV_HANDLER, + ZEND_DEFINED_SPEC_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_TYPE_CHECK_SPEC_CONST_HANDLER, + ZEND_TYPE_CHECK_SPEC_TMP_HANDLER, + ZEND_TYPE_CHECK_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_TYPE_CHECK_SPEC_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FE_RESET_RW_SPEC_CONST_HANDLER, + ZEND_FE_RESET_RW_SPEC_TMP_HANDLER, + ZEND_FE_RESET_RW_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FE_RESET_RW_SPEC_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FE_FREE_SPEC_TMPVAR_HANDLER, + ZEND_FE_FREE_SPEC_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER, + ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER, + ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER, + ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_HANDLER, + ZEND_DO_UCALL_SPEC_RETVAL_USED_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_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_NULL_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_VAR_CV_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_CV_CONST_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_PRE_DEC_OBJ_SPEC_VAR_CONST_HANDLER, + ZEND_PRE_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER, + ZEND_PRE_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_DEC_OBJ_SPEC_VAR_CV_HANDLER, + ZEND_PRE_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER, + ZEND_PRE_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_PRE_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_DEC_OBJ_SPEC_UNUSED_CV_HANDLER, + ZEND_PRE_DEC_OBJ_SPEC_CV_CONST_HANDLER, + ZEND_PRE_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_PRE_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_DEC_OBJ_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_POST_INC_OBJ_SPEC_VAR_CONST_HANDLER, + ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER, + ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_INC_OBJ_SPEC_VAR_CV_HANDLER, + ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER, + ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_HANDLER, + ZEND_POST_INC_OBJ_SPEC_CV_CONST_HANDLER, + ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_INC_OBJ_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_POST_DEC_OBJ_SPEC_VAR_CONST_HANDLER, + ZEND_POST_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER, + ZEND_POST_DEC_OBJ_SPEC_VAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_DEC_OBJ_SPEC_VAR_CV_HANDLER, + ZEND_POST_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER, + ZEND_POST_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_POST_DEC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_DEC_OBJ_SPEC_UNUSED_CV_HANDLER, + ZEND_POST_DEC_OBJ_SPEC_CV_CONST_HANDLER, + ZEND_POST_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_POST_DEC_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_DEC_OBJ_SPEC_CV_CV_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_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_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_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_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER, + ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER, + ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER, + ZEND_INSTANCEOF_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_DECLARE_CLASS_SPEC_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_DECLARE_INHERITED_CLASS_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_DECLARE_FUNCTION_SPEC_HANDLER, + ZEND_YIELD_FROM_SPEC_CONST_HANDLER, + ZEND_YIELD_FROM_SPEC_TMP_HANDLER, + ZEND_YIELD_FROM_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_YIELD_FROM_SPEC_CV_HANDLER, + ZEND_DECLARE_CONST_SPEC_CONST_CONST_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_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ADD_INTERFACE_SPEC_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_VERIFY_ABSTRACT_CLASS_SPEC_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_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_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_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_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_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_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER, + ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, + ZEND_USER_OPCODE_SPEC_HANDLER, + ZEND_ASSERT_CHECK_SPEC_HANDLER, + ZEND_JMP_SET_SPEC_CONST_HANDLER, + ZEND_JMP_SET_SPEC_TMP_HANDLER, + ZEND_JMP_SET_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_JMP_SET_SPEC_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_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_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ADD_TRAIT_SPEC_HANDLER, + ZEND_BIND_TRAITS_SPEC_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SEPARATE_SPEC_VAR_UNUSED_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_CLASS_NAME_SPEC_HANDLER, + ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, + ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, + ZEND_YIELD_SPEC_CONST_CONST_HANDLER, + ZEND_YIELD_SPEC_CONST_TMP_HANDLER, + ZEND_YIELD_SPEC_CONST_VAR_HANDLER, + ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER, + ZEND_YIELD_SPEC_CONST_CV_HANDLER, + ZEND_YIELD_SPEC_TMP_CONST_HANDLER, + ZEND_YIELD_SPEC_TMP_TMP_HANDLER, + ZEND_YIELD_SPEC_TMP_VAR_HANDLER, + ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER, + ZEND_YIELD_SPEC_TMP_CV_HANDLER, + ZEND_YIELD_SPEC_VAR_CONST_HANDLER, + ZEND_YIELD_SPEC_VAR_TMP_HANDLER, + ZEND_YIELD_SPEC_VAR_VAR_HANDLER, + ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER, + ZEND_YIELD_SPEC_VAR_CV_HANDLER, + ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER, + ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER, + ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER, + ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_YIELD_SPEC_UNUSED_CV_HANDLER, + ZEND_YIELD_SPEC_CV_CONST_HANDLER, + ZEND_YIELD_SPEC_CV_TMP_HANDLER, + ZEND_YIELD_SPEC_CV_VAR_HANDLER, + ZEND_YIELD_SPEC_CV_UNUSED_HANDLER, + ZEND_YIELD_SPEC_CV_CV_HANDLER, + ZEND_GENERATOR_RETURN_SPEC_CONST_HANDLER, + ZEND_GENERATOR_RETURN_SPEC_TMP_HANDLER, + ZEND_GENERATOR_RETURN_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_GENERATOR_RETURN_SPEC_CV_HANDLER, + ZEND_FAST_CALL_SPEC_HANDLER, + ZEND_FAST_RET_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_POW_SPEC_CONST_CONST_HANDLER, + ZEND_POW_SPEC_CONST_TMPVAR_HANDLER, + ZEND_POW_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POW_SPEC_CONST_CV_HANDLER, + ZEND_POW_SPEC_TMPVAR_CONST_HANDLER, + ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POW_SPEC_TMPVAR_CV_HANDLER, + ZEND_POW_SPEC_TMPVAR_CONST_HANDLER, + ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POW_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POW_SPEC_CV_CONST_HANDLER, + ZEND_POW_SPEC_CV_TMPVAR_HANDLER, + ZEND_POW_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POW_SPEC_CV_CV_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_NULL_HANDLER, + ZEND_ASSIGN_POW_SPEC_VAR_CONST_HANDLER, + ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_POW_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_POW_SPEC_VAR_UNUSED_HANDLER, + ZEND_ASSIGN_POW_SPEC_VAR_CV_HANDLER, + ZEND_ASSIGN_POW_SPEC_UNUSED_CONST_HANDLER, + ZEND_ASSIGN_POW_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_POW_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_POW_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_ASSIGN_POW_SPEC_UNUSED_CV_HANDLER, + ZEND_ASSIGN_POW_SPEC_CV_CONST_HANDLER, + ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_POW_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_POW_SPEC_CV_UNUSED_HANDLER, + ZEND_ASSIGN_POW_SPEC_CV_CV_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_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_COALESCE_SPEC_CONST_HANDLER, + ZEND_COALESCE_SPEC_TMP_HANDLER, + ZEND_COALESCE_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_COALESCE_SPEC_CV_HANDLER, + ZEND_SPACESHIP_SPEC_CONST_CONST_HANDLER, + ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER, + ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SPACESHIP_SPEC_CONST_CV_HANDLER, + ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER, + ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER, + ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER, + ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SPACESHIP_SPEC_CV_CONST_HANDLER, + ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER, + ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SPACESHIP_SPEC_CV_CV_HANDLER, + ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_DECLARE_ANON_INHERITED_CLASS_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_CONST_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_CV_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_R_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_CONST_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_CV_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_W_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_CONST_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_CV_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_RW_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_CONST_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_CV_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_IS_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CONST_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CV_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CONST_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CV_VAR_HANDLER, + ZEND_FETCH_STATIC_PROP_UNSET_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_CONST_VAR_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_CV_VAR_HANDLER, + ZEND_UNSET_STATIC_PROP_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CONST_VAR_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CONST_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_VAR_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CV_VAR_HANDLER, + ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_CV_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST_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_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_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_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_BIND_LEXICAL_SPEC_TMP_CV_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_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_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_BIND_STATIC_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_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_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_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_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_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_TMPVARCV_HANDLER, + ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_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_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_TMPVARCV_HANDLER, + ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_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_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_SUB_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_SUB_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + 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_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_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_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_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_TMPVARCV_HANDLER, + ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_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_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_TMPVARCV_HANDLER, + ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_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_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_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_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_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_TMPVARCV_HANDLER, + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_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, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_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, + 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_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_TMPVARCV_HANDLER, + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_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, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_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, + 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_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_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_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_TMPVARCV_HANDLER, + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_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, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_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, + 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_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_TMPVARCV_HANDLER, + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_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, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_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, + 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_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_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_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_TMPVARCV_HANDLER, + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_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, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_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, + 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_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_TMPVARCV_HANDLER, + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_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, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_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, + 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_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_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_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_TMPVARCV_HANDLER, + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_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, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_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, + 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_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_TMPVARCV_HANDLER, + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_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, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_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, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_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_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER, + ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_INC_LONG_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_DEC_LONG_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER, + ZEND_PRE_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_HANDLER, + ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_INC_LONG_SPEC_TMPVARCV_HANDLER, + ZEND_POST_INC_LONG_SPEC_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_INC_LONG_SPEC_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER, + ZEND_POST_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_INC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_HANDLER, + ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_DEC_LONG_SPEC_TMPVARCV_HANDLER, + ZEND_POST_DEC_LONG_SPEC_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_DEC_LONG_SPEC_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER, + ZEND_POST_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POST_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER, + ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST_HANDLER, + ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_HANDLER, + ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_HANDLER, + ZEND_QM_ASSIGN_NOREF_SPEC_CONST_HANDLER, + ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER, + ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER + }; + static const uint32_t specs[] = { + 0, + 1 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 26 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 51 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 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, + 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, + 411 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 436 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 461 | SPEC_RULE_OP1, + 466 | SPEC_RULE_OP1, + 471 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 496 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 521 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 546 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 571 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 596 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 621 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 646 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 671 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 696 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 721 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 746 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL, + 756 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL, + 766 | SPEC_RULE_OP1, + 771 | SPEC_RULE_OP1, + 776 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_RETVAL, + 826 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 851 | SPEC_RULE_OP1, + 3845, + 856, + 857 | SPEC_RULE_OP1, + 862 | SPEC_RULE_OP1, + 867 | SPEC_RULE_OP1, + 872 | SPEC_RULE_OP1, + 877 | SPEC_RULE_OP1, + 882 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 3845, + 3845, + 3845, + 907 | SPEC_RULE_OP1, + 912 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 937 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 962 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 987 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1012, + 1013 | SPEC_RULE_OP1, + 1018 | SPEC_RULE_OP2, + 1023 | SPEC_RULE_RETVAL, + 1025 | SPEC_RULE_OP2, + 1030 | SPEC_RULE_OP1, + 1035, + 1036 | SPEC_RULE_OP2, + 1041 | SPEC_RULE_OP1, + 1046 | SPEC_RULE_OP1 | SPEC_RULE_QUICK_ARG, + 1056 | SPEC_RULE_OP1, + 1061 | SPEC_RULE_OP1, + 1066 | SPEC_RULE_OP2, + 1071 | SPEC_RULE_OP1, + 1076 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1101 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1126 | SPEC_RULE_OP1, + 1131 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1156 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1181 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1206 | SPEC_RULE_OP1, + 1211 | SPEC_RULE_OP1, + 1216 | SPEC_RULE_OP1, + 1221 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1246 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1271 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1296 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1321 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1346 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1371 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1396 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1421 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1446 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1471 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1496 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1521 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1546 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1571 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1596 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1621 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1646 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1671 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1696 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 3845, + 1721, + 1722, + 1723, + 1724, + 1725, + 1726 | SPEC_RULE_OP1, + 1731 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1756 | SPEC_RULE_OP1, + 1761 | SPEC_RULE_OP2, + 1766 | SPEC_RULE_OP1, + 1771 | SPEC_RULE_OP1, + 1776 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1801 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1826 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1851 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1876 | SPEC_RULE_OP1 | SPEC_RULE_QUICK_ARG, + 1886 | SPEC_RULE_OP1, + 1891 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1916, + 1917 | SPEC_RULE_OP1, + 1922 | SPEC_RULE_OP1, + 1927 | SPEC_RULE_OP1, + 1932 | SPEC_RULE_OP1, + 1937 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 1962 | SPEC_RULE_OP1, + 1967 | SPEC_RULE_OP1, + 1972 | SPEC_RULE_OP1, + 1977 | SPEC_RULE_OP2, + 1982 | SPEC_RULE_RETVAL, + 1984 | SPEC_RULE_RETVAL, + 1986 | SPEC_RULE_RETVAL, + 1988 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2013 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2038 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2063 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2088 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_OP_DATA, + 2213, + 2214 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2239, + 2240 | SPEC_RULE_OP2, + 2245, + 2246 | SPEC_RULE_OP1, + 2251 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2276 | SPEC_RULE_OP2, + 2281 | SPEC_RULE_OP2, + 2286, + 2287 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_OP_DATA, + 2412 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2437, + 2438, + 2439, + 2440 | SPEC_RULE_OP1, + 2445 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2470, + 2471, + 2472 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2497, + 2498, + 2499, + 2500 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2525 | SPEC_RULE_OP1, + 2530, + 2531, + 2532, + 2533, + 2534 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2559 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2584 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2609 | SPEC_RULE_OP1, + 2614 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2639, + 2640 | SPEC_RULE_OP2, + 2645 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2670 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2695 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2720 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2745 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2770 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2795 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2820 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2845 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2870 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 2895 | SPEC_RULE_OP1 | SPEC_RULE_OP2, + 3845 + }; + zend_opcode_handlers = labels; + zend_handlers_count = sizeof(labels) / sizeof(void*); + zend_spec_handlers = specs; +} + +static HashTable *zend_handlers_table = NULL; + +static void init_opcode_serialiser(void) +{ + int i; + zval tmp; + + zend_handlers_table = malloc(sizeof(HashTable)); + zend_hash_init_ex(zend_handlers_table, zend_handlers_count, NULL, NULL, 1, 0); + zend_hash_real_init(zend_handlers_table, 0); + Z_TYPE_INFO(tmp) = IS_LONG; + for (i = 0; i < zend_handlers_count; i++) { + Z_LVAL(tmp) = i; + zend_hash_index_add(zend_handlers_table, (zend_long)(zend_uintptr_t)zend_opcode_handlers[i], &tmp); + } +} + +ZEND_API void zend_serialize_opcode_handler(zend_op *op) +{ + zval *zv; + + if (!zend_handlers_table) { + init_opcode_serialiser(); + } + zv = zend_hash_index_find(zend_handlers_table, (zend_long)(zend_uintptr_t)op->handler); + ZEND_ASSERT(zv != NULL); + op->handler = (const void *)(zend_uintptr_t)Z_LVAL_P(zv); } + +ZEND_API void zend_deserialize_opcode_handler(zend_op *op) +{ + op->handler = zend_opcode_handlers[(zend_uintptr_t)op->handler]; +} + +static const void *zend_vm_get_opcode_handler_ex(uint32_t spec, const zend_op* op) +{ + static const int zend_vm_decode[] = { + _UNUSED_CODE, /* 0 */ + _CONST_CODE, /* 1 = IS_CONST */ + _TMP_CODE, /* 2 = IS_TMP_VAR */ + _UNUSED_CODE, /* 3 */ + _VAR_CODE, /* 4 = IS_VAR */ + _UNUSED_CODE, /* 5 */ + _UNUSED_CODE, /* 6 */ + _UNUSED_CODE, /* 7 */ + _UNUSED_CODE, /* 8 = IS_UNUSED */ + _UNUSED_CODE, /* 9 */ + _UNUSED_CODE, /* 10 */ + _UNUSED_CODE, /* 11 */ + _UNUSED_CODE, /* 12 */ + _UNUSED_CODE, /* 13 */ + _UNUSED_CODE, /* 14 */ + _UNUSED_CODE, /* 15 */ + _CV_CODE /* 16 = IS_CV */ + }; + uint32_t offset = 0; + if (spec & SPEC_RULE_OP1) offset = offset * 5 + zend_vm_decode[op->op1_type]; + if (spec & SPEC_RULE_OP2) offset = offset * 5 + zend_vm_decode[op->op2_type]; + if (spec & SPEC_RULE_OP_DATA) offset = offset * 5 + zend_vm_decode[(op + 1)->op1_type]; + if (spec & SPEC_RULE_RETVAL) offset = offset * 2 + (op->result_type != IS_UNUSED); + if (spec & SPEC_RULE_QUICK_ARG) offset = offset * 2 + (op->op2.num < MAX_ARG_FLAG_NUM); + if (spec & SPEC_RULE_SMART_BRANCH) { + offset = offset * 3; + if ((op+1)->opcode == ZEND_JMPZ) { + offset += 1; + } else if ((op+1)->opcode == ZEND_JMPNZ) { + offset += 2; + } + } + return zend_opcode_handlers[(spec & SPEC_START_MASK) + offset]; +} + static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op) { - static const int zend_vm_decode[] = { - _UNUSED_CODE, /* 0 */ - _CONST_CODE, /* 1 = IS_CONST */ - _TMP_CODE, /* 2 = IS_TMP_VAR */ - _UNUSED_CODE, /* 3 */ - _VAR_CODE, /* 4 = IS_VAR */ - _UNUSED_CODE, /* 5 */ - _UNUSED_CODE, /* 6 */ - _UNUSED_CODE, /* 7 */ - _UNUSED_CODE, /* 8 = IS_UNUSED */ - _UNUSED_CODE, /* 9 */ - _UNUSED_CODE, /* 10 */ - _UNUSED_CODE, /* 11 */ - _UNUSED_CODE, /* 12 */ - _UNUSED_CODE, /* 13 */ - _UNUSED_CODE, /* 14 */ - _UNUSED_CODE, /* 15 */ - _CV_CODE /* 16 = IS_CV */ - }; - return zend_opcode_handlers[opcode * 25 + zend_vm_decode[op->op1_type] * 5 + zend_vm_decode[op->op2_type]]; + return zend_vm_get_opcode_handler_ex(zend_spec_handlers[opcode], op); } ZEND_API void zend_vm_set_opcode_handler(zend_op* op) @@ -49976,6 +60697,196 @@ ZEND_API void zend_vm_set_opcode_handler(zend_op* op) op->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], 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) +{ + zend_uchar opcode = zend_user_opcodes[op->opcode]; + uint32_t spec = zend_spec_handlers[opcode]; + switch (opcode) { + case ZEND_ADD: + 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 = 2920 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + 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 = 2945 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + 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 = 2970 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + if (op->op1_type > op->op2_type) { + zend_swap_operands(op); + } + } + break; + case ZEND_SUB: + 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 = 2995 | 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 = 3020 | 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 = 3045 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + } + break; + case ZEND_MUL: + 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 = 3070 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + 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 = 3095 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + 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 = 3120 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + if (op->op1_type > op->op2_type) { + zend_swap_operands(op); + } + } + break; + case ZEND_IS_EQUAL: + if ((op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG)) { + if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { + break; + } + spec = 3145 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + 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 = 3220 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + if (op->op1_type > op->op2_type) { + zend_swap_operands(op); + } + } + break; + case ZEND_IS_NOT_EQUAL: + if ((op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG)) { + if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { + break; + } + spec = 3295 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + 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 = 3370 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + if (op->op1_type > op->op2_type) { + zend_swap_operands(op); + } + } + break; + case ZEND_IS_SMALLER: + if ((op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG)) { + if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { + break; + } + spec = 3445 | 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 = 3520 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + } + break; + case ZEND_IS_SMALLER_OR_EQUAL: + if ((op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG)) { + if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { + break; + } + spec = 3595 | 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 = 3670 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + } + break; + case ZEND_QM_ASSIGN: + if ((op1_info == MAY_BE_DOUBLE)) { + spec = 3835 | 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 = 3840 | SPEC_RULE_OP1; + } + break; + case ZEND_PRE_INC: + if ((res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG)) { + spec = 3745 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + } else if ((op1_info == MAY_BE_LONG)) { + spec = 3755 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + } else if ((op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE))) { + spec = 3765 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + } + break; + case ZEND_PRE_DEC: + if ((res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG)) { + spec = 3775 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + } else if ((op1_info == MAY_BE_LONG)) { + spec = 3785 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + } else if ((op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE))) { + spec = 3795 | SPEC_RULE_OP1 | SPEC_RULE_RETVAL; + } + break; + case ZEND_POST_INC: + if ((res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG)) { + spec = 3805 | SPEC_RULE_OP1; + } else if ((op1_info == MAY_BE_LONG)) { + spec = 3810 | SPEC_RULE_OP1; + } else if ((op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE))) { + spec = 3815 | SPEC_RULE_OP1; + } + break; + case ZEND_POST_DEC: + if ((res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG)) { + spec = 3820 | SPEC_RULE_OP1; + } else if ((op1_info == MAY_BE_LONG)) { + spec = 3825 | SPEC_RULE_OP1; + } else if ((op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE))) { + spec = 3830 | SPEC_RULE_OP1; + } + break; + default: + break; + } + op->handler = zend_vm_get_opcode_handler_ex(spec, op); +} + ZEND_API int zend_vm_call_opcode_handler(zend_execute_data* ex) { int ret; diff --git a/Zend/zend_vm_execute.skl b/Zend/zend_vm_execute.skl index 7e223385ff..ff877df76e 100644 --- a/Zend/zend_vm_execute.skl +++ b/Zend/zend_vm_execute.skl @@ -11,7 +11,7 @@ ZEND_API void {%EXECUTOR_NAME%}_ex(zend_execute_data *ex) LOAD_OPLINE(); while (1) { - {%ZEND_VM_CONTINUE_LABEL%} + {%ZEND_VM_CONTINUE_LABEL%} {%ZEND_VM_DISPATCH%} { {%INTERNAL_EXECUTOR%} } @@ -45,5 +45,40 @@ ZEND_API void zend_{%EXECUTOR_NAME%}(zend_op_array *op_array, zval *return_value void {%INITIALIZER_NAME%}(void) { - {%EXTERNAL_LABELS%} + {%EXTERNAL_LABELS%} } + +static HashTable *zend_handlers_table = NULL; + +static void init_opcode_serialiser(void) +{ + int i; + zval tmp; + + zend_handlers_table = malloc(sizeof(HashTable)); + zend_hash_init_ex(zend_handlers_table, zend_handlers_count, NULL, NULL, 1, 0); + zend_hash_real_init(zend_handlers_table, 0); + Z_TYPE_INFO(tmp) = IS_LONG; + for (i = 0; i < zend_handlers_count; i++) { + Z_LVAL(tmp) = i; + zend_hash_index_add(zend_handlers_table, (zend_long)(zend_uintptr_t)zend_opcode_handlers[i], &tmp); + } +} + +ZEND_API void zend_serialize_opcode_handler(zend_op *op) +{ + zval *zv; + + if (!zend_handlers_table) { + init_opcode_serialiser(); + } + zv = zend_hash_index_find(zend_handlers_table, (zend_long)(zend_uintptr_t)op->handler); + ZEND_ASSERT(zv != NULL); + op->handler = (const void *)(zend_uintptr_t)Z_LVAL_P(zv); +} + +ZEND_API void zend_deserialize_opcode_handler(zend_op *op) +{ + op->handler = zend_opcode_handlers[(zend_uintptr_t)op->handler]; +} + diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index c633124904..4407d7dfe3 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -54,6 +54,85 @@ define("ZEND_VM_KIND_CALL", 1); define("ZEND_VM_KIND_SWITCH", 2); define("ZEND_VM_KIND_GOTO", 3); +$vm_op_flags = array( + "ZEND_VM_OP_SPEC" => 1<<0, + "ZEND_VM_OP_CONST" => 1<<1, + "ZEND_VM_OP_TMPVAR" => 1<<2, + "ZEND_VM_OP_TMPVARCV" => 1<<3, + "ZEND_VM_OP_MASK" => 0xf0, + "ZEND_VM_OP_NUM" => 0x10, + "ZEND_VM_OP_JMP_ADDR" => 0x20, + "ZEND_VM_OP_TRY_CATCH" => 0x30, + "ZEND_VM_OP_LIVE_RANGE" => 0x40, + "ZEND_VM_OP_THIS" => 0x50, + "ZEND_VM_OP_NEXT" => 0x60, + "ZEND_VM_OP_CLASS_FETCH" => 0x70, + "ZEND_VM_OP_CONSTRUCTOR" => 0x80, + + "ZEND_VM_EXT_VAR_FETCH" => 1<<16, + "ZEND_VM_EXT_ISSET" => 1<<17, + "ZEND_VM_EXT_ARG_NUM" => 1<<18, + "ZEND_VM_EXT_ARRAY_INIT" => 1<<19, + "ZEND_VM_EXT_REF" => 1<<20, + "ZEND_VM_EXT_MASK" => 0x0f000000, + "ZEND_VM_EXT_NUM" => 0x01000000, + // unused 0x2000000 + "ZEND_VM_EXT_JMP_ADDR" => 0x03000000, + "ZEND_VM_EXT_DIM_OBJ" => 0x04000000, + "ZEND_VM_EXT_CLASS_FETCH" => 0x05000000, + "ZEND_VM_EXT_CONST_FETCH" => 0x06000000, + "ZEND_VM_EXT_TYPE" => 0x07000000, + "ZEND_VM_EXT_EVAL" => 0x08000000, + "ZEND_VM_EXT_FAST_CALL" => 0x09000000, + "ZEND_VM_EXT_FAST_RET" => 0x0a000000, + "ZEND_VM_EXT_SRC" => 0x0b000000, + "ZEND_VM_EXT_SEND" => 0x0c000000, + "ZEND_VM_NO_CONST_CONST" => 0x40000000, + "ZEND_VM_COMMUTATIVE" => 0x80000000, +); + +foreach ($vm_op_flags as $name => $val) { + define($name, $val); +} + +$vm_op_decode = array( + "ANY" => 0, + "CONST" => ZEND_VM_OP_SPEC | ZEND_VM_OP_CONST, + "TMP" => ZEND_VM_OP_SPEC, + "VAR" => ZEND_VM_OP_SPEC, + "UNUSED" => ZEND_VM_OP_SPEC, + "CV" => ZEND_VM_OP_SPEC, + "TMPVAR" => ZEND_VM_OP_SPEC | ZEND_VM_OP_TMPVAR, + "TMPVARCV" => ZEND_VM_OP_SPEC | ZEND_VM_OP_TMPVARCV, + "NUM" => ZEND_VM_OP_NUM, + "JMP_ADDR" => ZEND_VM_OP_JMP_ADDR, + "TRY_CATCH" => ZEND_VM_OP_TRY_CATCH, + "LIVE_RANGE" => ZEND_VM_OP_LIVE_RANGE, + "THIS" => ZEND_VM_OP_THIS, + "NEXT" => ZEND_VM_OP_NEXT, + "CLASS_FETCH" => ZEND_VM_OP_CLASS_FETCH, + "CONSTRUCTOR" => ZEND_VM_OP_CONSTRUCTOR, +); + +$vm_ext_decode = array( + "NUM" => ZEND_VM_EXT_NUM, + "JMP_ADDR" => ZEND_VM_EXT_JMP_ADDR, + "DIM_OBJ" => ZEND_VM_EXT_DIM_OBJ, + "CLASS_FETCH" => ZEND_VM_EXT_CLASS_FETCH, + "CONST_FETCH" => ZEND_VM_EXT_CONST_FETCH, + "VAR_FETCH" => ZEND_VM_EXT_VAR_FETCH, + "ARRAY_INIT" => ZEND_VM_EXT_ARRAY_INIT, + "TYPE" => ZEND_VM_EXT_TYPE, + "EVAL" => ZEND_VM_EXT_EVAL, + "FAST_CALL" => ZEND_VM_EXT_FAST_CALL, + "FAST_RET" => ZEND_VM_EXT_FAST_RET, + "ISSET" => ZEND_VM_EXT_ISSET, + "ARG_NUM" => ZEND_VM_EXT_ARG_NUM, + "REF" => ZEND_VM_EXT_REF, + "SRC" => ZEND_VM_EXT_SRC, + "SEND" => ZEND_VM_EXT_SEND, +); + $vm_kind_name = array( ZEND_VM_KIND_CALL => "ZEND_VM_KIND_CALL", ZEND_VM_KIND_SWITCH => "ZEND_VM_KIND_SWITCH", @@ -77,346 +156,447 @@ $op_types_ex = array( "UNUSED", "CV", "TMPVAR", + "TMPVARCV", ); $prefix = array( - "ANY" => "", - "TMP" => "_TMP", - "VAR" => "_VAR", - "CONST" => "_CONST", - "UNUSED" => "_UNUSED", - "CV" => "_CV", - "TMPVAR" => "_TMPVAR", + "ANY" => "", + "TMP" => "_TMP", + "VAR" => "_VAR", + "CONST" => "_CONST", + "UNUSED" => "_UNUSED", + "CV" => "_CV", + "TMPVAR" => "_TMPVAR", + "TMPVARCV" => "_TMPVARCV", ); $typecode = array( - "ANY" => 0, - "TMP" => 1, - "VAR" => 2, - "CONST" => 0, - "UNUSED" => 3, - "CV" => 4, - "TMPVAR" => 0, + "ANY" => 0, + "TMP" => 1, + "VAR" => 2, + "CONST" => 0, + "UNUSED" => 3, + "CV" => 4, + "TMPVAR" => 0, + "TMPVARCV" => 0, +); + +$commutative_order = array( + "ANY" => 0, + "TMP" => 1, + "VAR" => 2, + "CONST" => 0, + "UNUSED" => 0, + "CV" => 4, + "TMPVAR" => 2, + "TMPVARCV" => 4, ); $op1_type = array( - "ANY" => "opline->op1_type", - "TMP" => "IS_TMP_VAR", - "VAR" => "IS_VAR", - "CONST" => "IS_CONST", - "UNUSED" => "IS_UNUSED", - "CV" => "IS_CV", - "TMPVAR" => "(IS_TMP_VAR|IS_VAR)", + "ANY" => "opline->op1_type", + "TMP" => "IS_TMP_VAR", + "VAR" => "IS_VAR", + "CONST" => "IS_CONST", + "UNUSED" => "IS_UNUSED", + "CV" => "IS_CV", + "TMPVAR" => "(IS_TMP_VAR|IS_VAR)", + "TMPVARCV" => "(IS_TMP_VAR|IS_VAR|IS_CV)", ); $op2_type = array( - "ANY" => "opline->op2_type", - "TMP" => "IS_TMP_VAR", - "VAR" => "IS_VAR", - "CONST" => "IS_CONST", - "UNUSED" => "IS_UNUSED", - "CV" => "IS_CV", - "TMPVAR" => "(IS_TMP_VAR|IS_VAR)", + "ANY" => "opline->op2_type", + "TMP" => "IS_TMP_VAR", + "VAR" => "IS_VAR", + "CONST" => "IS_CONST", + "UNUSED" => "IS_UNUSED", + "CV" => "IS_CV", + "TMPVAR" => "(IS_TMP_VAR|IS_VAR)", + "TMPVARCV" => "(IS_TMP_VAR|IS_VAR|IS_CV)", ); $op1_free = array( - "ANY" => "(free_op1 != NULL)", - "TMP" => "1", - "VAR" => "(free_op1 != NULL)", - "CONST" => "0", - "UNUSED" => "0", - "CV" => "0", - "TMPVAR" => "???", + "ANY" => "(free_op1 != NULL)", + "TMP" => "1", + "VAR" => "(free_op1 != NULL)", + "CONST" => "0", + "UNUSED" => "0", + "CV" => "0", + "TMPVAR" => "???", + "TMPVARCV" => "???", ); $op2_free = array( - "ANY" => "(free_op2 != NULL)", - "TMP" => "1", - "VAR" => "(free_op2 != NULL)", - "CONST" => "0", - "UNUSED" => "0", - "CV" => "0", - "TMPVAR" => "???", + "ANY" => "(free_op2 != NULL)", + "TMP" => "1", + "VAR" => "(free_op2 != NULL)", + "CONST" => "0", + "UNUSED" => "0", + "CV" => "0", + "TMPVAR" => "???", + "TMPVARCV" => "???", ); $op1_get_zval_ptr = array( - "ANY" => "get_zval_ptr(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", - "VAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", - "CONST" => "EX_CONSTANT(opline->op1)", - "UNUSED" => "NULL", - "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var)", - "TMPVAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", + "ANY" => "get_zval_ptr(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", + "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", + "VAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", + "CONST" => "EX_CONSTANT(opline->op1)", + "UNUSED" => "NULL", + "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var)", + "TMPVAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", + "TMPVARCV" => "???", ); $op2_get_zval_ptr = array( - "ANY" => "get_zval_ptr(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", - "VAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", - "CONST" => "EX_CONSTANT(opline->op2)", - "UNUSED" => "NULL", - "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var)", - "TMPVAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", + "ANY" => "get_zval_ptr(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", + "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", + "VAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", + "CONST" => "EX_CONSTANT(opline->op2)", + "UNUSED" => "NULL", + "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var)", + "TMPVAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", + "TMPVARCV" => "???", ); $op1_get_zval_ptr_ptr = array( - "ANY" => "get_zval_ptr_ptr(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", - "TMP" => "NULL", - "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1)", - "CONST" => "NULL", - "UNUSED" => "NULL", - "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var)", - "TMPVAR" => "???", + "ANY" => "get_zval_ptr_ptr(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", + "TMP" => "NULL", + "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1)", + "CONST" => "NULL", + "UNUSED" => "NULL", + "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var)", + "TMPVAR" => "???", + "TMPVARCV" => "???", ); $op2_get_zval_ptr_ptr = array( - "ANY" => "get_zval_ptr_ptr(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", - "TMP" => "NULL", - "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2)", - "CONST" => "NULL", - "UNUSED" => "NULL", - "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var)", - "TMPVAR" => "???", + "ANY" => "get_zval_ptr_ptr(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", + "TMP" => "NULL", + "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2)", + "CONST" => "NULL", + "UNUSED" => "NULL", + "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var)", + "TMPVAR" => "???", + "TMPVARCV" => "???", ); $op1_get_zval_ptr_deref = array( - "ANY" => "get_zval_ptr_deref(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", - "VAR" => "_get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1)", - "CONST" => "EX_CONSTANT(opline->op1)", - "UNUSED" => "NULL", - "CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op1.var)", - "TMPVAR" => "???", + "ANY" => "get_zval_ptr_deref(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", + "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", + "VAR" => "_get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1)", + "CONST" => "EX_CONSTANT(opline->op1)", + "UNUSED" => "NULL", + "CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op1.var)", + "TMPVAR" => "???", + "TMPVARCV" => "???", ); $op2_get_zval_ptr_deref = array( - "ANY" => "get_zval_ptr_deref(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", - "VAR" => "_get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2)", - "CONST" => "EX_CONSTANT(opline->op2)", - "UNUSED" => "NULL", - "CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op2.var)", - "TMPVAR" => "???", + "ANY" => "get_zval_ptr_deref(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", + "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", + "VAR" => "_get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2)", + "CONST" => "EX_CONSTANT(opline->op2)", + "UNUSED" => "NULL", + "CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op2.var)", + "TMPVAR" => "???", + "TMPVARCV" => "???", ); $op1_get_zval_ptr_undef = array( - "ANY" => "get_zval_ptr_undef(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", - "VAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", - "CONST" => "EX_CONSTANT(opline->op1)", - "UNUSED" => "NULL", - "CV" => "_get_zval_ptr_cv_undef(execute_data, opline->op1.var)", - "TMPVAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", + "ANY" => "get_zval_ptr_undef(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", + "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", + "VAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", + "CONST" => "EX_CONSTANT(opline->op1)", + "UNUSED" => "NULL", + "CV" => "_get_zval_ptr_cv_undef(execute_data, opline->op1.var)", + "TMPVAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", + "TMPVARCV" => "EX_VAR(opline->op1.var)", ); $op2_get_zval_ptr_undef = array( - "ANY" => "get_zval_ptr_undef(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", - "VAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", - "CONST" => "EX_CONSTANT(opline->op2)", - "UNUSED" => "NULL", - "CV" => "_get_zval_ptr_cv_undef(execute_data, opline->op2.var)", - "TMPVAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", + "ANY" => "get_zval_ptr_undef(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", + "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", + "VAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", + "CONST" => "EX_CONSTANT(opline->op2)", + "UNUSED" => "NULL", + "CV" => "_get_zval_ptr_cv_undef(execute_data, opline->op2.var)", + "TMPVAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", + "TMPVARCV" => "EX_VAR(opline->op2.var)", ); $op1_get_zval_ptr_ptr_undef = array( - "ANY" => "get_zval_ptr_ptr_undef(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", - "TMP" => "NULL", - "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1)", - "CONST" => "NULL", - "UNUSED" => "NULL", - "CV" => "_get_zval_ptr_cv_undef_\\1(execute_data, opline->op1.var)", - "TMPVAR" => "???", + "ANY" => "get_zval_ptr_ptr_undef(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", + "TMP" => "NULL", + "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1)", + "CONST" => "NULL", + "UNUSED" => "NULL", + "CV" => "_get_zval_ptr_cv_undef_\\1(execute_data, opline->op1.var)", + "TMPVAR" => "???", + "TMPVARCV" => "EX_VAR(opline->op1.var)", ); $op2_get_zval_ptr_ptr_undef = array( - "ANY" => "get_zval_ptr_ptr_undef(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", - "TMP" => "NULL", - "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2)", - "CONST" => "NULL", - "UNUSED" => "NULL", - "CV" => "_get_zval_ptr_cv_undef_\\1(execute_data, opline->op2.var)", - "TMPVAR" => "???", + "ANY" => "get_zval_ptr_ptr_undef(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", + "TMP" => "NULL", + "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2)", + "CONST" => "NULL", + "UNUSED" => "NULL", + "CV" => "_get_zval_ptr_cv_undef_\\1(execute_data, opline->op2.var)", + "TMPVAR" => "???", + "TMPVARCV" => "EX_VAR(opline->op2.var)", ); $op1_get_obj_zval_ptr = array( - "ANY" => "get_obj_zval_ptr(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", - "VAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", - "CONST" => "EX_CONSTANT(opline->op1)", - "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", - "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var)", - "TMPVAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", + "ANY" => "get_obj_zval_ptr(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", + "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", + "VAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", + "CONST" => "EX_CONSTANT(opline->op1)", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", + "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var)", + "TMPVAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", + "TMPVARCV" => "???", ); $op2_get_obj_zval_ptr = array( - "ANY" => "get_obj_zval_ptr(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", - "VAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", - "CONST" => "EX_CONSTANT(opline->op2)", - "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", - "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var)", - "TMPVAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", + "ANY" => "get_obj_zval_ptr(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", + "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", + "VAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", + "CONST" => "EX_CONSTANT(opline->op2)", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", + "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var)", + "TMPVAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", + "TMPVARCV" => "???", ); $op1_get_obj_zval_ptr_undef = array( - "ANY" => "get_obj_zval_ptr_undef(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", - "VAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", - "CONST" => "EX_CONSTANT(opline->op1)", - "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", - "CV" => "_get_zval_ptr_cv_undef(execute_data, opline->op1.var)", - "TMPVAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", + "ANY" => "get_obj_zval_ptr_undef(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", + "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", + "VAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", + "CONST" => "EX_CONSTANT(opline->op1)", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", + "CV" => "_get_zval_ptr_cv_undef(execute_data, opline->op1.var)", + "TMPVAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", + "TMPVARCV" => "EX_VAR(opline->op1.var)", ); $op2_get_obj_zval_ptr_undef = array( - "ANY" => "get_obj_zval_ptr_undef(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", - "VAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", - "CONST" => "EX_CONSTANT(opline->op2)", - "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", - "CV" => "_get_zval_ptr_cv_undef(execute_data, opline->op2.var)", - "TMPVAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", + "ANY" => "get_obj_zval_ptr_undef(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", + "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", + "VAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", + "CONST" => "EX_CONSTANT(opline->op2)", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", + "CV" => "_get_zval_ptr_cv_undef(execute_data, opline->op2.var)", + "TMPVAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", + "TMPVARCV" => "EX_VAR(opline->op2.var)", ); $op1_get_obj_zval_ptr_deref = array( - "ANY" => "get_obj_zval_ptr(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", - "VAR" => "_get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1)", - "CONST" => "EX_CONSTANT(opline->op1)", - "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", - "CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op1.var)", - "TMPVAR" => "???", + "ANY" => "get_obj_zval_ptr(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", + "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", + "VAR" => "_get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1)", + "CONST" => "EX_CONSTANT(opline->op1)", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", + "CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op1.var)", + "TMPVAR" => "???", + "TMPVARCV" => "???", ); $op2_get_obj_zval_ptr_deref = array( - "ANY" => "get_obj_zval_ptr(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", - "VAR" => "_get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2)", - "CONST" => "EX_CONSTANT(opline->op2)", - "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", - "CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op2.var)", - "TMPVAR" => "???", + "ANY" => "get_obj_zval_ptr(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", + "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", + "VAR" => "_get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2)", + "CONST" => "EX_CONSTANT(opline->op2)", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", + "CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op2.var)", + "TMPVAR" => "???", + "TMPVARCV" => "???", ); $op1_get_obj_zval_ptr_ptr = array( - "ANY" => "get_obj_zval_ptr_ptr(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", - "TMP" => "NULL", - "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1)", - "CONST" => "NULL", - "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", - "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var)", - "TMPVAR" => "???", + "ANY" => "get_obj_zval_ptr_ptr(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", + "TMP" => "NULL", + "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1)", + "CONST" => "NULL", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", + "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var)", + "TMPVAR" => "???", + "TMPVARCV" => "???", ); $op2_get_obj_zval_ptr_ptr = array( - "ANY" => "get_obj_zval_ptr_ptr(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", - "TMP" => "NULL", - "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2)", - "CONST" => "NULL", - "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", - "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var)", - "TMPVAR" => "???", + "ANY" => "get_obj_zval_ptr_ptr(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", + "TMP" => "NULL", + "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2)", + "CONST" => "NULL", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", + "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var)", + "TMPVAR" => "???", + "TMPVARCV" => "???", ); $op1_get_obj_zval_ptr_ptr_undef = array( - "ANY" => "get_obj_zval_ptr_ptr(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", - "TMP" => "NULL", - "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1)", - "CONST" => "NULL", - "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", - "CV" => "_get_zval_ptr_cv_undef_\\1(execute_data, opline->op1.var)", - "TMPVAR" => "???", + "ANY" => "get_obj_zval_ptr_ptr(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)", + "TMP" => "NULL", + "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1)", + "CONST" => "NULL", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", + "CV" => "_get_zval_ptr_cv_undef_\\1(execute_data, opline->op1.var)", + "TMPVAR" => "???", + "TMPVARCV" => "EX_VAR(opline->op1.var)", ); $op2_get_obj_zval_ptr_ptr_undef = array( - "ANY" => "get_obj_zval_ptr_ptr(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", - "TMP" => "NULL", - "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2)", - "CONST" => "NULL", - "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", - "CV" => "_get_zval_ptr_cv_undef_\\1(execute_data, opline->op2.var)", - "TMPVAR" => "???", + "ANY" => "get_obj_zval_ptr_ptr(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)", + "TMP" => "NULL", + "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2)", + "CONST" => "NULL", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", + "CV" => "_get_zval_ptr_cv_undef_\\1(execute_data, opline->op2.var)", + "TMPVAR" => "???", + "TMPVARCV" => "EX_VAR(opline->op2.var)", ); $op1_free_op = array( - "ANY" => "FREE_OP(free_op1)", - "TMP" => "zval_ptr_dtor_nogc(free_op1)", - "VAR" => "zval_ptr_dtor_nogc(free_op1)", - "CONST" => "", - "UNUSED" => "", - "CV" => "", - "TMPVAR" => "zval_ptr_dtor_nogc(free_op1)", + "ANY" => "FREE_OP(free_op1)", + "TMP" => "zval_ptr_dtor_nogc(free_op1)", + "VAR" => "zval_ptr_dtor_nogc(free_op1)", + "CONST" => "", + "UNUSED" => "", + "CV" => "", + "TMPVAR" => "zval_ptr_dtor_nogc(free_op1)", + "TMPVARCV" => "???", ); $op2_free_op = array( - "ANY" => "FREE_OP(free_op2)", - "TMP" => "zval_ptr_dtor_nogc(free_op2)", - "VAR" => "zval_ptr_dtor_nogc(free_op2)", - "CONST" => "", - "UNUSED" => "", - "CV" => "", - "TMPVAR" => "zval_ptr_dtor_nogc(free_op2)", + "ANY" => "FREE_OP(free_op2)", + "TMP" => "zval_ptr_dtor_nogc(free_op2)", + "VAR" => "zval_ptr_dtor_nogc(free_op2)", + "CONST" => "", + "UNUSED" => "", + "CV" => "", + "TMPVAR" => "zval_ptr_dtor_nogc(free_op2)", + "TMPVARCV" => "???", ); $op1_free_op_if_var = array( - "ANY" => "if (opline->op1_type == IS_VAR) {zval_ptr_dtor_nogc(free_op1);}", - "TMP" => "", - "VAR" => "zval_ptr_dtor_nogc(free_op1)", - "CONST" => "", - "UNUSED" => "", - "CV" => "", - "TMPVAR" => "???", + "ANY" => "if (opline->op1_type == IS_VAR) {zval_ptr_dtor_nogc(free_op1);}", + "TMP" => "", + "VAR" => "zval_ptr_dtor_nogc(free_op1)", + "CONST" => "", + "UNUSED" => "", + "CV" => "", + "TMPVAR" => "???", + "TMPVARCV" => "???", ); $op2_free_op_if_var = array( - "ANY" => "if (opline->op2_type == IS_VAR) {zval_ptr_dtor_nogc(free_op2);}", - "TMP" => "", - "VAR" => "zval_ptr_dtor_nogc(free_op2)", - "CONST" => "", - "UNUSED" => "", - "CV" => "", - "TMPVAR" => "???", + "ANY" => "if (opline->op2_type == IS_VAR) {zval_ptr_dtor_nogc(free_op2);}", + "TMP" => "", + "VAR" => "zval_ptr_dtor_nogc(free_op2)", + "CONST" => "", + "UNUSED" => "", + "CV" => "", + "TMPVAR" => "???", + "TMPVARCV" => "???", ); $op1_free_op_var_ptr = array( - "ANY" => "if (free_op1) {zval_ptr_dtor_nogc(free_op1);}", - "TMP" => "", - "VAR" => "if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}", - "CONST" => "", - "UNUSED" => "", - "CV" => "", - "TMPVAR" => "???", + "ANY" => "if (free_op1) {zval_ptr_dtor_nogc(free_op1);}", + "TMP" => "", + "VAR" => "if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}", + "CONST" => "", + "UNUSED" => "", + "CV" => "", + "TMPVAR" => "???", + "TMPVARCV" => "???", ); $op2_free_op_var_ptr = array( - "ANY" => "if (free_op2) {zval_ptr_dtor_nogc(free_op2);}", - "TMP" => "", - "VAR" => "if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);}", - "CONST" => "", - "UNUSED" => "", - "CV" => "", - "TMPVAR" => "???", + "ANY" => "if (free_op2) {zval_ptr_dtor_nogc(free_op2);}", + "TMP" => "", + "VAR" => "if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);}", + "CONST" => "", + "UNUSED" => "", + "CV" => "", + "TMPVAR" => "???", + "TMPVARCV" => "???", ); $op1_free_unfetched = array( - "ANY" => "FREE_UNFETCHED_OP(opline->op1_type, opline->op1.var)", - "TMP" => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))", - "VAR" => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))", - "CONST" => "", - "UNUSED" => "", - "CV" => "", - "TMPVAR" => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))", + "ANY" => "FREE_UNFETCHED_OP(opline->op1_type, opline->op1.var)", + "TMP" => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))", + "VAR" => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))", + "CONST" => "", + "UNUSED" => "", + "CV" => "", + "TMPVAR" => "zval_ptr_dtor_nogc(EX_VAR(opline->op1.var))", + "TMPVARCV" => "???", ); $op2_free_unfetched = array( - "ANY" => "FREE_UNFETCHED_OP(opline->op2_type, opline->op2.var)", - "TMP" => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))", - "VAR" => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))", - "CONST" => "", - "UNUSED" => "", - "CV" => "", - "TMPVAR" => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))", + "ANY" => "FREE_UNFETCHED_OP(opline->op2_type, opline->op2.var)", + "TMP" => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))", + "VAR" => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))", + "CONST" => "", + "UNUSED" => "", + "CV" => "", + "TMPVAR" => "zval_ptr_dtor_nogc(EX_VAR(opline->op2.var))", + "TMPVARCV" => "???", +); + +$op_data_type = array( + "ANY" => "(opline+1)->op1_type", + "TMP" => "IS_TMP_VAR", + "VAR" => "IS_VAR", + "CONST" => "IS_CONST", + "UNUSED" => "IS_UNUSED", + "CV" => "IS_CV", + "TMPVAR" => "(IS_TMP_VAR|IS_VAR)", + "TMPVARCV" => "(IS_TMP_VAR|IS_VAR|IS_CV)", +); + +$op_data_get_zval_ptr = array( + "ANY" => "get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data, \\1)", + "TMP" => "_get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data)", + "VAR" => "_get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data)", + "CONST" => "EX_CONSTANT((opline+1)->op1)", + "UNUSED" => "NULL", + "CV" => "_get_zval_ptr_cv_\\1(execute_data, (opline+1)->op1.var)", + "TMPVAR" => "_get_zval_ptr_var((opline+1)->op1.var, execute_data, &free_op_data)", + "TMPVARCV" => "???", +); + +$op_data_get_zval_ptr_deref = array( + "ANY" => "get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data, \\1)", + "TMP" => "_get_zval_ptr_tmp((opline+1)->op1.var, execute_data, &free_op_data)", + "VAR" => "_get_zval_ptr_var_deref((opline+1)->op1.var, execute_data, &free_op_data)", + "CONST" => "EX_CONSTANT((opline+1)->op1)", + "UNUSED" => "NULL", + "CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, (opline+1)->op1.var)", + "TMPVAR" => "???", + "TMPVARCV" => "???", +); + +$op_data_free_op = array( + "ANY" => "FREE_OP(free_op_data)", + "TMP" => "zval_ptr_dtor_nogc(free_op_data)", + "VAR" => "zval_ptr_dtor_nogc(free_op_data)", + "CONST" => "", + "UNUSED" => "", + "CV" => "", + "TMPVAR" => "zval_ptr_dtor_nogc(free_op_data)", + "TMPVARCV" => "???", +); + +$op_data_free_unfetched = array( + "ANY" => "FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var)", + "TMP" => "zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var))", + "VAR" => "zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var))", + "CONST" => "", + "UNUSED" => "", + "CV" => "", + "TMPVAR" => "zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var))", + "TMPVARCV" => "???", ); $list = array(); // list of opcode handlers and helpers in original order @@ -426,6 +606,8 @@ $params = array(); // parameters of helpers $opnames = array(); // opcode name to code mapping $line_no = 1; +$used_extra_spec = array(); + // Writes $s into resulting executor function out($f, $s) { global $line_no; @@ -461,8 +643,27 @@ function helper_name($name, $spec, $op1, $op2) { return $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]; } +function opcode_name($name, $spec, $op1, $op2) { + global $prefix, $opnames, $opcodes; + + if (isset($opnames[$name])) { + $opcode = $opcodes[$opnames[$name]]; + // If we haven't helper with specified spicialized operands then + // using unspecialized helper + if (!isset($opcode["op1"][$op1]) && + isset($opcode["op1"]["ANY"])) { + $op1 = "ANY"; + } + if (!isset($opcode["op2"][$op2]) && + isset($opcode["op2"]["ANY"])) { + $op2 = "ANY"; + } + } + return $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]; +} + // Generates code for opcode handler or helper -function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { +function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name, $extra_spec=null) { global $op1_type, $op2_type, $op1_get_zval_ptr, $op2_get_zval_ptr, $op1_get_zval_ptr_deref, $op2_get_zval_ptr_deref, $op1_get_zval_ptr_undef, $op2_get_zval_ptr_undef, @@ -475,7 +676,9 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { $op1_get_obj_zval_ptr_ptr_undef, $op2_get_obj_zval_ptr_ptr_undef, $op1_free, $op2_free, $op1_free_unfetched, $op2_free_unfetched, $op1_free_op, $op2_free_op, $op1_free_op_if_var, $op2_free_op_if_var, - $op1_free_op_var_ptr, $op2_free_op_var_ptr, $prefix; + $op1_free_op_var_ptr, $op2_free_op_var_ptr, $prefix, + $op_data_type, $op_data_get_zval_ptr, $op_data_get_zval_ptr_deref, + $op_data_free_op, $op_data_free_unfetched; // Specializing $code = preg_replace( @@ -521,7 +724,15 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { "/^#(\s*)if\s+1\s*\\|\\|.*[^\\\\]$/m", "/^#(\s*)if\s+0\s*&&.*[^\\\\]$/m", "/^#(\s*)ifdef\s+ZEND_VM_EXPORT\s*\n/m", - "/^#(\s*)ifndef\s+ZEND_VM_EXPORT\s*\n/m" + "/^#(\s*)ifndef\s+ZEND_VM_EXPORT\s*\n/m", + "/OP_DATA_TYPE/", + "/GET_OP_DATA_ZVAL_PTR\(([^)]*)\)/", + "/GET_OP_DATA_ZVAL_PTR_DEREF\(([^)]*)\)/", + "/FREE_OP_DATA\(\)/", + "/FREE_UNFETCHED_OP_DATA\(\)/", + "/RETURN_VALUE_USED\(opline\)/", + "/arg_num <= MAX_ARG_FLAG_NUM/", + "/ZEND_VM_SMART_BRANCH\(\s*([^,)]*)\s*,\s*([^)]*)\s*\)/", ), array( $op1_type[$op1], @@ -560,12 +771,25 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { ($op1!="ANY"||$op2!="ANY")?"#\\1if 0\n":"#\\1if 1\n", ($op1!="ANY"||$op2!="ANY")?"0":"1", ($op1!="ANY"||$op2!="ANY")?"1":"0", - "\\1".(($spec && $kind != ZEND_VM_KIND_CALL)?("_SPEC".$prefix[$op1].$prefix[$op2]):""), - "goto \\1".(($spec && $kind != ZEND_VM_KIND_CALL)?("_SPEC".$prefix[$op1].$prefix[$op2]):""), + "\\1".(($spec && $kind != ZEND_VM_KIND_CALL)?("_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec)):""), + "goto \\1".(($spec && $kind != ZEND_VM_KIND_CALL)?("_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec)):""), "#\\1if 1", "#\\1if 0", $export?"#\\1if 1\n":"#\\1if 0\n", - $export?"#\\1if 0\n":"#\\1if 1\n" + $export?"#\\1if 0\n":"#\\1if 1\n", + $op_data_type[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"], + $op_data_get_zval_ptr[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"], + $op_data_get_zval_ptr_deref[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"], + $op_data_free_op[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"], + $op_data_free_unfetched[isset($extra_spec['OP_DATA']) ? $extra_spec['OP_DATA'] : "ANY"], + isset($extra_spec['RETVAL']) ? $extra_spec['RETVAL'] : "RETURN_VALUE_USED(opline)", + isset($extra_spec['QUICK_ARG']) ? $extra_spec['QUICK_ARG'] : "arg_num <= MAX_ARG_FLAG_NUM", + isset($extra_spec['SMART_BRANCH']) ? + ($extra_spec['SMART_BRANCH'] == 1 ? + "ZEND_VM_SMART_BRANCH_JMPZ(\\1, \\2)" + : ($extra_spec['SMART_BRANCH'] == 2 ? + "ZEND_VM_SMART_BRANCH_JMPNZ(\\1, \\2)" : "")) + : "ZEND_VM_SMART_BRANCH(\\1, \\2)", ), $code); @@ -579,17 +803,20 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { array( "/EXECUTE_DATA/m", "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m", - "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/m", - "/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*[A-Za-z_]*\s*,\s*(.*)\s*\);/m", + "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m", ), function($matches) use ($spec, $prefix, $op1, $op2) { if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) { return "execute_data"; } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) { - return "ZEND_VM_TAIL_CALL(" . $matches[1] . ($spec?"_SPEC":"") . $prefix[$op1] . $prefix[$op2] . "_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))"; - } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HELPER_EX", strlen("ZEND_VM_DISPATCH_TO_HELPER_EX")) == 0) { - return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2) . "(" . $matches[2]. " ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));"; + return "ZEND_VM_TAIL_CALL(" . opcode_name($matches[1], $spec, $op1, $op2) . "_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))"; } else { + // ZEND_VM_DISPATCH_TO_HELPER + if (isset($matches[2])) { + // extra args + $args = substr(preg_replace("/,\s*[A-Za-z_]*\s*,\s*([^,)\s]*)\s*/", ", $1", $matches[2]), 2); + return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2) . "(" . $args. " ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC))"; + } return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))"; } }, @@ -600,17 +827,20 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { array( "/EXECUTE_DATA/m", "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m", - "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/m", - "/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*([A-Za-z_]*)\s*,\s*(.*)\s*\);/m", + "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m", ), function($matches) use ($spec, $prefix, $op1, $op2) { if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) { return "execute_data"; } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) { - return "goto " . $matches[1] . ($spec?"_SPEC":"") . $prefix[$op1] . $prefix[$op2] . "_LABEL"; - } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HELPER_EX", strlen("ZEND_VM_DISPATCH_TO_HELPER_EX")) == 0) { - return $matches[2] . " = " . $matches[3] . "; goto " . helper_name($matches[1], $spec, $op1, $op2) . ";"; + return "goto " . opcode_name($matches[1], $spec, $op1, $op2) . "_LABEL"; } else { + // ZEND_VM_DISPATCH_TO_HELPER + if (isset($matches[2])) { + // extra args + $args = preg_replace("/,\s*([A-Za-z_]*)\s*,\s*([^,)\s]*)\s*/", "$1 = $2; ", $matches[2]); + return $args . "goto " . helper_name($matches[1], $spec, $op1, $op2); + } return "goto " . helper_name($matches[1], $spec, $op1, $op2); } }, @@ -621,17 +851,20 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { array( "/EXECUTE_DATA/m", "/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m", - "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/m", - "/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*([A-Za-z_]*)\s*,\s*(.*)\s*\);/m", + "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m", ), function($matches) use ($spec, $prefix, $op1, $op2) { if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) { return "execute_data"; } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) { - return "goto " . $matches[1] . ($spec?"_SPEC":"") . $prefix[$op1] . $prefix[$op2] . "_HANDLER"; - } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HELPER_EX", strlen("ZEND_VM_DISPATCH_TO_HELPER_EX")) == 0) { - return $matches[2] . " = " . $matches[3] . "; goto " . helper_name($matches[1], $spec, $op1, $op2) . ";"; + return "goto " . opcode_name($matches[1], $spec, $op1, $op2) . "_HANDLER"; } else { + // ZEND_VM_DISPATCH_TO_HELPER + if (isset($matches[2])) { + // extra args + $args = preg_replace("/,\s*([A-Za-z_]*)\s*,\s*([^,)\s]*)\s*/", "$1 = $2; ", $matches[2]); + return $args . "goto " . helper_name($matches[1], $spec, $op1, $op2); + } return "goto " . helper_name($matches[1], $spec, $op1, $op2); } }, @@ -648,6 +881,7 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { } $del_free_op1 = (strpos($code, "free_op1") === false); $del_free_op2 = (strpos($code, "free_op2") === false); + $del_free_op_data = (strpos($code, "free_op_data") === false); $n = 0; foreach ($matches as $match) { $dcl = $match[0]; @@ -662,6 +896,11 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { $dcl = preg_replace("/free_op2\s*;/", ";", $dcl); $changed = 1; } + if ($del_free_op_data && strpos($dcl, "free_op_data") !== false) { + $dcl = preg_replace("/free_op_data\s*,\s*/", "", $dcl); + $dcl = preg_replace("/free_op_data\s*;/", ";", $dcl); + $changed = 1; + } if ($changed) { $dcl = preg_replace("/,\s*;/", ";", $dcl); $dcl = preg_replace("/zend_free_op\s*;/", "", $dcl); @@ -681,42 +920,59 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { } // Generates opcode handler -function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno) { - global $definition_file, $prefix, $typecode, $opnames; +function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno, $extra_spec = null, &$switch_labels = array()) { + global $definition_file, $prefix, $typecode, $opnames, $commutative_order; + + if ($spec && + isset($extra_spec["NO_CONST_CONST"]) && + $op1 == "CONST" && $op2 == "CONST") { + // Skip useless constant handlers + return; + } + + if ($spec && + isset($extra_spec["COMMUTATIVE"]) && + $commutative_order[$op1] > $commutative_order[$op2]) { + // Skip duplicate commutative handlers + return; + } if (ZEND_VM_LINES) { out($f, "#line $lineno \"$definition_file\"\n"); } // Generate opcode handler's entry point according to selected threading model + $spec_name = $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].($spec?extra_spec_name($extra_spec):""); switch($kind) { case ZEND_VM_KIND_CALL: - out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ".$name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n"); + out($f,"static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL {$spec_name}_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n"); break; case ZEND_VM_KIND_SWITCH: if ($spec) { - out($f,"case ".((string)($opnames[$name]*25+($typecode[$op1=="TMPVAR"?"TMP":$op1]*5)+$typecode[$op2=="TMPVAR"?"TMP":$op2])).": /*".$name."_SPEC".$prefix[$op1].$prefix[$op2]."_HANDLER*/"); + $cur = $switch_labels ? end($switch_labels) + 1 : 0; + out($f,"case $cur: /* $spec_name */"); + $switch_labels[$spec_name] = $cur; } else { out($f,"case ".$name.":"); } if ($use) { // This handler is used by other handlers. We will add label to call it. - out($f," ".$name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."_LABEL:\n"); + out($f," {$spec_name}_LABEL:\n"); } else { out($f,"\n"); } break; case ZEND_VM_KIND_GOTO: - out($f,$name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."_HANDLER: ZEND_VM_GUARD(".$name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2].");\n"); + out($f,"{$spec_name}_HANDLER: ZEND_VM_GUARD($spec_name);\n"); break; } // Generate opcode handler's code - gen_code($f, $spec, $kind, 0, $code, $op1, $op2, $name); + gen_code($f, $spec, $kind, 0, $code, $op1, $op2, $name, $extra_spec); } // Generates helper -function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno) { +function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno, $inline) { global $definition_file, $prefix; if (ZEND_VM_LINES) { @@ -726,12 +982,19 @@ function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno) // Generate helper's entry point according to selected threading model switch($kind) { case ZEND_VM_KIND_CALL: + if ($inline) { + $zend_always_inline = " zend_always_inline"; + $zend_fastcall = ""; + } else { + $zend_always_inline = ""; + $zend_fastcall = " ZEND_FASTCALL"; + } if ($param == null) { // Helper without parameters - out($f, "static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ".$name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."(ZEND_OPCODE_HANDLER_ARGS)\n"); + out($f, "static$zend_always_inline ZEND_OPCODE_HANDLER_RET$zend_fastcall ".$name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."(ZEND_OPCODE_HANDLER_ARGS)\n"); } else { // Helper with parameter - out($f, "static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ".$name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."(".$param." ZEND_OPCODE_HANDLER_ARGS_DC)\n"); + out($f, "static$zend_always_inline ZEND_OPCODE_HANDLER_RET$zend_fastcall ".$name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."(".$param." ZEND_OPCODE_HANDLER_ARGS_DC)\n"); } break; case ZEND_VM_KIND_SWITCH: @@ -746,103 +1009,205 @@ function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno) gen_code($f, $spec, $kind, 0, $code, $op1, $op2, $name); } + +function gen_null_label($f, $kind, $prolog) { + switch ($kind) { + case ZEND_VM_KIND_CALL: + out($f,$prolog."ZEND_NULL_HANDLER,\n"); + break; + case ZEND_VM_KIND_SWITCH: + out($f,$prolog."(void*)(uintptr_t)-1,\n"); + break; + case ZEND_VM_KIND_GOTO: + out($f,$prolog."(void*)&&ZEND_NULL_HANDLER,\n"); + break; + } +} + // Generates array of opcode handlers (specialized or unspecialized) -function gen_labels($f, $spec, $kind, $prolog) { - global $opcodes, $op_types, $prefix, $typecode; +function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()) { + global $opcodes, $op_types, $prefix; $next = 0; + $label = 0; if ($spec) { // Emit labels for specialized executor // For each opcode in opcode number order foreach($opcodes as $num => $dsc) { - while ($next != $num) { - // If some opcode numbers are not used then fill hole with pointers - // to handler of undefined opcode - $op1t = $op_types; - // For each op1.op_type except ANY - foreach($op1t as $op1) { - if ($op1 != "ANY") { - $op2t = $op_types; - // For each op2.op_type except ANY - foreach($op2t as $op2) { - if ($op2 != "ANY") { - // Emit pointer to handler of undefined opcode - switch ($kind) { - case ZEND_VM_KIND_CALL: - out($f,$prolog."ZEND_NULL_HANDLER,\n"); - break; - case ZEND_VM_KIND_SWITCH: - out($f,$prolog."(void*)(uintptr_t)-1,\n"); - break; - case ZEND_VM_KIND_GOTO: - out($f,$prolog."(void*)&&ZEND_NULL_HANDLER,\n"); - break; + $specs[$num] = "$label"; + $spec_op1 = $spec_op2 = $spec_extra = false; + $next = $num + 1; + $diff = array_diff_key(array_flip($op_types), isset($dsc["op1"]) ? $dsc["op1"] : array()); + if ((count($diff) == count($op_types) - 1 ? isset($diff["ANY"]) : count($diff) != count($op_types)) || isset($dsc["op1"]["TMPVAR"]) || isset($dsc["op1"]["TMPVARCV"])) { + $spec_op1 = true; + $specs[$num] .= " | SPEC_RULE_OP1"; + } + $diff = array_diff_key(array_flip($op_types), isset($dsc["op2"]) ? $dsc["op2"] : array()); + if ((count($diff) == count($op_types) - 1 ? isset($diff["ANY"]) : count($diff) != count($op_types)) || isset($dsc["op2"]["TMPVAR"]) || isset($dsc["op2"]["TMPVARCV"])) { + $spec_op2 = true; + $specs[$num] .= " | SPEC_RULE_OP2"; + } + $spec_extra = call_user_func_array("array_merge", extra_spec_handler($dsc) ?: array(array())); + $flags = extra_spec_flags($spec_extra); + if ($flags) { + $specs[$num] .= " | ".implode("|", $flags); + } + if ($num >= 256) { + $opcodes[$num]['spec_code'] = $specs[$num]; + unset($specs[$num]); + } + + $foreach_op1 = function($do) use ($dsc, $op_types) { + return function() use ($do, $dsc, $op_types) { + // For each op1.op_type except ANY + foreach($op_types as $op1) { + if ($op1 != "ANY") { + if (!isset($dsc["op1"][$op1])) { + if ($op1 == "TMP" || $op1 == "VAR") { + if (isset($dsc["op1"]["TMPVAR"])) { + $op1 = "TMPVAR"; + } else if (isset($dsc["op1"]["TMPVARCV"])) { + $op1 = "TMPVARCV"; + } else { + $op1 = "ANY"; + } + } else if ($op1 == "CV" && isset($dsc["op1"]["TMPVARCV"])) { + $op1 = "TMPVARCV"; + } else { + // Try to use unspecialized handler + $op1 = "ANY"; } } + $do($op1, "ANY"); } } - } - $next++; - } - $next = $num + 1; - $op1t = $op_types; - // For each op1.op_type except ANY - foreach($op1t as $op1) { - if ($op1 != "ANY") { - if (!isset($dsc["op1"][$op1])) { - if (($op1 == "TMP" || $op1 == "VAR") && isset($dsc["op1"]["TMPVAR"])) { - $op1 = "TMPVAR"; - } else { - // Try to use unspecialized handler - $op1 = "ANY"; - } - } - $op2t = $op_types; + }; + }; + $foreach_op2 = function($do) use ($dsc, $op_types) { + return function($op1) use ($do, $dsc, $op_types) { // For each op2.op_type except ANY - foreach($op2t as $op2) { + foreach($op_types as $op2) { if ($op2 != "ANY") { if (!isset($dsc["op2"][$op2])) { - if (($op2 == "TMP" || $op2 == "VAR") && isset($dsc["op2"]["TMPVAR"])) { - $op2 = "TMPVAR"; + if ($op2 == "TMP" || $op2 == "VAR") { + if (isset($dsc["op2"]["TMPVAR"])) { + $op2 = "TMPVAR"; + } else if (isset($dsc["op2"]["TMPVARCV"])) { + $op2 = "TMPVARCV"; + } else { + $op2 = "ANY"; + } + } else if ($op2 == "CV" && isset($dsc["op2"]["TMPVARCV"])) { + $op2 = "TMPVARCV"; } else { // Try to use unspecialized handler $op2 = "ANY"; } } - // Check if specialized handler is defined - if (isset($dsc["op1"][$op1]) && - isset($dsc["op2"][$op2])) { - // Emit pointer to specialized handler - switch ($kind) { - case ZEND_VM_KIND_CALL: - out($f,$prolog.$dsc["op"]."_SPEC".$prefix[$op1].$prefix[$op2]."_HANDLER,\n"); - break; - case ZEND_VM_KIND_SWITCH: - out($f,$prolog."(void*)(uintptr_t)".((string)($num*25+$typecode[$op1=="TMPVAR"?"TMP":$op1]*5+$typecode[$op2=="TMPVAR"?"TMP":$op2])).",\n"); - break; - case ZEND_VM_KIND_GOTO: - out($f,$prolog."(void*)&&".$dsc["op"]."_SPEC".$prefix[$op1].$prefix[$op2]."_HANDLER,\n"); - break; - } - } else { - // Emit pinter to handler of undefined opcode - switch ($kind) { - case ZEND_VM_KIND_CALL: - out($f,$prolog."ZEND_NULL_HANDLER,\n"); - break; - case ZEND_VM_KIND_SWITCH: - out($f,$prolog."(void*)(uintptr_t)-1,\n"); - break; - case ZEND_VM_KIND_GOTO: - out($f,$prolog."(void*)&&ZEND_NULL_HANDLER,\n"); - break; + $do($op1, $op2); + } + } + }; + }; + $foreach_op_data = function($do) use ($dsc, $op_types) { + return function($op1, $op2, $extra_spec = array()) use ($do, $dsc, $op_types) { + // For each op_data.op_type except ANY + foreach($op_types as $op_data) { + if ($op_data != "ANY") { + if (!isset($dsc["spec"]["OP_DATA"][$op_data])) { + if ($op_data == "TMP" || $op_data == "VAR") { + if (isset($dsc["spec"]["OP_DATA"]["TMPVAR"])) { + $op_data = "TMPVAR"; + } else if (isset($dsc["spec"]["OP_DATA"]["TMPVARCV"])) { + $op_data = "TMPVARCV"; + } else { + // Try to use unspecialized handler + $op_data = "ANY"; + } + } else if ($op_data == "CV" && isset($dsc["OP_DATA"]["TMPVARCV"])) { + $op_data = "TMPVARCV"; + } else { + // Try to use unspecialized handler + $op_data = "ANY"; } } + $do($op1, $op2, array("OP_DATA" => $op_data) + $extra_spec); } } + }; + }; + $foreach_extra_spec = function($do, $spec) use ($dsc) { + return function($op1, $op2, $extra_spec = array()) use ($do, $spec, $dsc) { + foreach ($dsc["spec"][$spec] as $val) { + $do($op1, $op2, array($spec => $val) + $extra_spec); + } + }; + }; + $generate = function ($op1, $op2, $extra_spec = array()) use ($f, $kind, $dsc, $prefix, $prolog, $num, $switch_labels, &$label) { + global $typecode, $commutative_order; + + // Check if specialized handler is defined + /* TODO: figure out better way to signal "specialized and not defined" than an extra lookup */ + if (isset($dsc["op1"][$op1]) && + isset($dsc["op2"][$op2]) && + (!isset($extra_spec["OP_DATA"]) || isset($dsc["spec"]["OP_DATA"][$extra_spec["OP_DATA"]]))) { + + if (isset($extra_spec["NO_CONST_CONST"]) && + $op1 == "CONST" && $op2 == "CONST") { + // Skip useless constant handlers + gen_null_label($f, $kind, $prolog); + $label++; + return; + } else if (isset($extra_spec["COMMUTATIVE"]) && + $commutative_order[$op1] > $commutative_order[$op2]) { + // Skip duplicate commutative handlers + gen_null_label($f, $kind, $prolog); + $label++; + return; + } + + // Emit pointer to specialized handler + $spec_name = $dsc["op"]."_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec); + switch ($kind) { + case ZEND_VM_KIND_CALL: + out($f,"$prolog{$spec_name}_HANDLER,\n"); + $label++; + break; + case ZEND_VM_KIND_SWITCH: + out($f,$prolog."(void*)(uintptr_t)$switch_labels[$spec_name],\n"); + $label++; + break; + case ZEND_VM_KIND_GOTO: + out($f,$prolog."(void*)&&{$spec_name}_HANDLER,\n"); + $label++; + break; + } + } else { + // Emit pointer to handler of undefined opcode + gen_null_label($f, $kind, $prolog); + $label++; + } + }; + + $do = $generate; + if ($spec_extra) { + foreach ($spec_extra as $extra => $devnull) { + if ($extra == "OP_DATA") { + $do = $foreach_op_data($do); + } else { + $do = $foreach_extra_spec($do, $extra); + } } } + if ($spec_op2) { + $do = $foreach_op2($do); + } + if ($spec_op1) { + $do = $foreach_op1($do); + } + + $do("ANY", "ANY"); } } else { // Emit labels for unspecialized executor @@ -865,6 +1230,9 @@ function gen_labels($f, $spec, $kind, $prolog) { } $next++; } + if ($num >= 256) { + continue; + } $next = $num+1; //ugly trick for ZEND_VM_DEFINE_OP @@ -909,6 +1277,21 @@ function gen_labels($f, $spec, $kind, $prolog) { out($f,$prolog."(void*)&&ZEND_NULL_HANDLER\n"); break; } + $specs[$num + 1] = "$label"; +} + +// Generates specialized offsets +function gen_specs($f, $spec, $kind, $prolog, $specs) { + $lastdef = array_pop($specs); + $last = 0; + foreach ($specs as $num => $def) { + while (++$last < $num) { + out($f, "$prolog$lastdef,\n"); + } + $last = $num; + out($f, "$prolog$def,\n"); + } + out($f, "$prolog$lastdef\n"); } // Generates handler for undefined opcodes (CALL threading model) @@ -929,8 +1312,87 @@ function gen_null_handler($f) { } } +function extra_spec_name($extra_spec) { + global $prefix; + + $s = ""; + if (isset($extra_spec["OP_DATA"])) { + $s .= "_OP_DATA" . $prefix[$extra_spec["OP_DATA"]]; + } + if (isset($extra_spec["RETVAL"])) { + $s .= "_RETVAL_".($extra_spec["RETVAL"] ? "USED" : "UNUSED"); + } + if (isset($extra_spec["QUICK_ARG"])) { + if ($extra_spec["QUICK_ARG"]) { + $s .= "_QUICK"; + } + } + if (isset($extra_spec["SMART_BRANCH"])) { + if ($extra_spec["SMART_BRANCH"] == 1) { + $s .= "_JMPZ"; + } else if ($extra_spec["SMART_BRANCH"] == 2) { + $s .= "_JMPNZ"; + } + } + return $s; +} + +function extra_spec_flags($extra_spec) { + $s = array(); + if (isset($extra_spec["OP_DATA"])) { + $s[] = "SPEC_RULE_OP_DATA"; + } + if (isset($extra_spec["RETVAL"])) { + $s[] = "SPEC_RULE_RETVAL"; + } + if (isset($extra_spec["QUICK_ARG"])) { + $s[] = "SPEC_RULE_QUICK_ARG"; + } + if (isset($extra_spec["SMART_BRANCH"])) { + $s[] = "SPEC_RULE_SMART_BRANCH"; + } + return $s; +} + +function extra_spec_handler($dsc) { + global $op_types_ex; + + if (!isset($dsc["spec"])) { + return array(array()); + } + $specs = $dsc["spec"]; + + if (isset($specs["OP_DATA"])) { + $op_data_specs = $specs["OP_DATA"]; + $specs["OP_DATA"] = array(); + foreach($op_types_ex as $op_data) { + if (isset($dsc["spec"]["OP_DATA"][$op_data])) { + $specs["OP_DATA"][] = $op_data; + } + } + } + + $f = function($specs) use (&$f) { + $spec = key($specs); + $top = array_shift($specs); + if ($specs) { + $next = $f($specs); + } else { + $next = array(array()); + } + $ret = array(); + foreach ($next as $existing) { + foreach ($top as $mode) { + $ret[] = array($spec => $mode) + $existing; + } + } + return $ret; + }; + return $f($specs); +} + // Generates all opcode handlers and helpers (specialized or unspecilaized) -function gen_executor_code($f, $spec, $kind, $prolog) { +function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array()) { global $list, $opcodes, $helpers, $op_types_ex; if ($spec) { @@ -945,11 +1407,13 @@ function gen_executor_code($f, $spec, $kind, $prolog) { foreach ($list as $lineno => $dsc) { if (isset($dsc["handler"])) { $num = $dsc["handler"]; - // Check if handler accepts such types of operands (op1 and op2) - if (isset($opcodes[$num]["op1"][$op1]) && - isset($opcodes[$num]["op2"][$op2])) { - // Generate handler code - gen_handler($f, 1, $kind, $opcodes[$num]["op"], $op1, $op2, isset($opcodes[$num]["use"]), $opcodes[$num]["code"], $lineno); + foreach (extra_spec_handler($opcodes[$num]) as $extra_spec) { + // Check if handler accepts such types of operands (op1 and op2) + if (isset($opcodes[$num]["op1"][$op1]) && + isset($opcodes[$num]["op2"][$op2])) { + // Generate handler code + gen_handler($f, 1, $kind, $opcodes[$num]["op"], $op1, $op2, isset($opcodes[$num]["use"]), $opcodes[$num]["code"], $lineno, $extra_spec, $switch_labels); + } } } else if (isset($dsc["helper"])) { $num = $dsc["helper"]; @@ -957,7 +1421,7 @@ function gen_executor_code($f, $spec, $kind, $prolog) { if (isset($helpers[$num]["op1"][$op1]) && isset($helpers[$num]["op2"][$op2])) { // Generate helper code - gen_helper($f, 1, $kind, $num, $op1, $op2, $helpers[$num]["param"], $helpers[$num]["code"], $lineno); + gen_helper($f, 1, $kind, $num, $op1, $op2, $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"]); } } else { var_dump($dsc); @@ -973,12 +1437,14 @@ function gen_executor_code($f, $spec, $kind, $prolog) { foreach ($list as $lineno => $dsc) { if (isset($dsc["handler"])) { $num = $dsc["handler"]; - // Generate handler code - gen_handler($f, 0, $kind, $opcodes[$num]["op"], "ANY", "ANY", isset($opcodes[$num]["use"]), $opcodes[$num]["code"], $lineno); + // Generate handler code + if ($num < 256) { + gen_handler($f, 0, $kind, $opcodes[$num]["op"], "ANY", "ANY", isset($opcodes[$num]["use"]), $opcodes[$num]["code"], $lineno); + } } else if (isset($dsc["helper"])) { $num = $dsc["helper"]; - // Generate helper code - gen_helper($f, 0, $kind, $num, "ANY", "ANY", $helpers[$num]["param"], $helpers[$num]["code"], $lineno); + // Generate helper code + gen_helper($f, 0, $kind, $num, "ANY", "ANY", $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"]); } else { var_dump($dsc); die("??? $kind:$num\n"); @@ -1019,14 +1485,25 @@ function skip_blanks($f, $prolog, $epilog) { function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) { global $params, $skeleton_file, $line_no; - $lineno = 0; + $switch_labels = array(); + $lineno = 0; foreach ($skl as $line) { // Skeleton file contains special markers in form %NAME% those are // substituted by custom code if (preg_match("/(.*)[{][%]([A-Z_]*)[%][}](.*)/", $line, $m)) { switch ($m[2]) { case "DEFINES": + out($f,"#define SPEC_START_MASK 0x0000ffff\n"); + out($f,"#define SPEC_RULE_OP1 0x00010000\n"); + out($f,"#define SPEC_RULE_OP2 0x00020000\n"); + out($f,"#define SPEC_RULE_OP_DATA 0x00040000\n"); + out($f,"#define SPEC_RULE_RETVAL 0x00080000\n"); + out($f,"#define SPEC_RULE_QUICK_ARG 0x00100000\n"); + out($f,"#define SPEC_RULE_SMART_BRANCH 0x00200000\n"); + out($f,"\n"); + out($f,"static const uint32_t *zend_spec_handlers;\n"); out($f,"static const void **zend_opcode_handlers;\n"); + out($f,"static int zend_handlers_count;\n"); out($f,"static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op);\n\n"); switch ($kind) { case ZEND_VM_KIND_CALL: @@ -1211,9 +1688,14 @@ 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"); - gen_labels($f, $spec, $kind, $prolog."\t\t"); + gen_labels($f, $spec, $kind, $prolog."\t\t", $specs); out($f,$prolog."\t};\n"); - out($f,$prolog."\tzend_opcode_handlers = (const void **)labels;\n"); + out($f,$prolog."static const uint32_t specs[] = {\n"); + gen_specs($f, $spec, $kind, $prolog."\t", $specs); + out($f,$prolog."};\n"); + out($f,$prolog."\tzend_opcode_handlers = (const void **) labels;\n"); + out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(void*);\n"); + out($f,$prolog."\tzend_spec_handlers = (const uint32_t *) specs;\n"); out($f,$prolog."\treturn;\n"); out($f,$prolog."}\n"); } else { @@ -1274,7 +1756,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) "#endif\n"); } else { // Emit executor code - gen_executor_code($f, $spec, $kind, $m[1]); + gen_executor_code($f, $spec, $kind, $m[1], $switch_labels); } break; case "EXTERNAL_EXECUTOR": @@ -1295,9 +1777,14 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) out($f,$prolog.$executor_name."_ex(NULL);\n"); } else { out($f,$prolog."static const void *labels[] = {\n"); - gen_labels($f, $spec, $kind, $prolog."\t"); + gen_labels($f, $spec, $kind, $prolog."\t", $specs, $switch_labels); + out($f,$prolog."};\n"); + out($f,$prolog."static const uint32_t specs[] = {\n"); + gen_specs($f, $spec, $kind, $prolog."\t", $specs); out($f,$prolog."};\n"); out($f,$prolog."zend_opcode_handlers = labels;\n"); + out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(void*);\n"); + out($f,$prolog."zend_spec_handlers = specs;\n"); } break; default: @@ -1310,9 +1797,90 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) } } +function parse_operand_spec($def, $lineno, $str, &$flags) { + global $vm_op_decode; + + $flags = 0; + $a = explode("|",$str); + foreach($a as $val) { + if (isset($vm_op_decode[$val])) { + $flags |= $vm_op_decode[$val]; + } else { + die("ERROR ($def:$lineno): Wrong operand type '$str'\n"); + } + } + if (!($flags & ZEND_VM_OP_SPEC)) { + if (count($a) != 1) { + die("ERROR ($def:$lineno): Wrong operand type '$str'\n"); + } + $a = array("ANY"); + } + return array_flip($a); +} + +function parse_ext_spec($def, $lineno, $str) { + global $vm_ext_decode; + + $flags = 0; + $a = explode("|",$str); + foreach($a as $val) { + if (isset($vm_ext_decode[$val])) { + $flags |= $vm_ext_decode[$val]; + } else { + die("ERROR ($def:$lineno): Wrong extended_value type '$str'\n"); + } + } + return $flags; +} + +function parse_spec_rules($def, $lineno, $str) { + global $used_extra_spec; + + $ret = array(); + $a = explode(",", $str); + foreach($a as $rule) { + $n = strpos($rule, "="); + if ($n !== false) { + $id = trim(substr($rule, 0, $n)); + $val = trim(substr($rule, $n+1)); + switch ($id) { + case "OP_DATA": + $ret["OP_DATA"] = parse_operand_spec($def, $lineno, $val, $devnull); + break; + default: + die("ERROR ($def:$lineno): Wrong specialization rules '$str'\n"); + } + $used_extra_spec[$id] = 1; + } else { + switch ($rule) { + case "RETVAL": + $ret["RETVAL"] = array(0, 1); + break; + case "QUICK_ARG": + $ret["QUICK_ARG"] = array(0, 1); + break; + case "SMART_BRANCH": + $ret["SMART_BRANCH"] = array(0, 1, 2); + break; + case "NO_CONST_CONST": + $ret["NO_CONST_CONST"] = array(1); + break; + case "COMMUTATIVE": + $ret["COMMUTATIVE"] = array(1); + break; + default: + die("ERROR ($def:$lineno): Wrong specialization rules '$str'\n"); + } + $used_extra_spec[$rule] = 1; + } + } + return $ret; +} + function gen_vm($def, $skel) { global $definition_file, $skeleton_file, $executor_file, - $op_types, $list, $opcodes, $helpers, $params, $opnames; + $op_types, $list, $opcodes, $helpers, $params, $opnames, + $vm_op_flags, $used_extra_spec; // Load definition file $in = @file($def); @@ -1336,13 +1904,14 @@ function gen_vm($def, $skel) { $helper = null; $max_opcode_len = 0; $max_opcode = 0; + $extra_num = 256; $export = array(); foreach ($in as $line) { ++$lineno; if (strpos($line,"ZEND_VM_HANDLER(") === 0) { // Parsing opcode handler's definition if (preg_match( - "/^ZEND_VM_HANDLER\(\s*([0-9]+)\s*,\s*([A-Z_]+)\s*,\s*([A-Z|]+)\s*,\s*([A-Z|]+)\s*\)/", + "/^ZEND_VM_HANDLER\(\s*([0-9]+)\s*,\s*([A-Z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/", $line, $m) == 0) { die("ERROR ($def:$lineno): Invalid ZEND_VM_HANDLER definition.\n"); @@ -1350,8 +1919,12 @@ function gen_vm($def, $skel) { $code = (int)$m[1]; $op = $m[2]; $len = strlen($op); - $op1 = array_flip(explode("|",$m[3])); - $op2 = array_flip(explode("|",$m[4])); + $op1 = parse_operand_spec($def, $lineno, $m[3], $flags1); + $op2 = parse_operand_spec($def, $lineno, $m[4], $flags2); + $flags = $flags1 | ($flags2 << 8); + if (!empty($m[6])) { + $flags |= parse_ext_spec($def, $lineno, $m[6]); + } if ($len > $max_opcode_len) { $max_opcode_len = $len; @@ -1365,48 +1938,88 @@ function gen_vm($def, $skel) { if (isset($opnames[$op])) { die("ERROR ($def:$lineno): Opcode with name '$op' is already defined.\n"); } - $opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>""); + $opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>"","flags"=>$flags); + if (isset($m[8])) { + $opcodes[$code]["spec"] = parse_spec_rules($def, $lineno, $m[8]); + if (isset($opcodes[$code]["spec"]["NO_CONST_CONST"])) { + $opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_NO_CONST_CONST"]; + } + if (isset($opcodes[$code]["spec"]["COMMUTATIVE"])) { + $opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_COMMUTATIVE"]; + } + } $opnames[$op] = $code; $handler = $code; $helper = null; $list[$lineno] = array("handler"=>$handler); - } else if (strpos($line,"ZEND_VM_HELPER(") === 0) { - // Parsing helper's definition + } else if (strpos($line,"ZEND_VM_TYPE_SPEC_HANDLER(") === 0) { + // Parsing opcode handler's definition if (preg_match( - "/^ZEND_VM_HELPER\(\s*([A-Za-z_]+)\s*,\s*([A-Z|]+)\s*,\s*([A-Z|]+)\s*\)/", + "/^ZEND_VM_TYPE_SPEC_HANDLER\(\s*([A-Z_]+)\s*,\s*([^,]+),\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/", $line, $m) == 0) { - die("ERROR ($def:$lineno): Invalid ZEND_VM_HELPER definition.\n"); + die("ERROR ($def:$lineno): Invalid ZEND_VM_TYPE_HANDLER_HANDLER definition.\n"); } - $helper = $m[1]; - $op1 = array_flip(explode("|",$m[2])); - $op2 = array_flip(explode("|",$m[3])); - if (isset($helpers[$helper])) { - die("ERROR ($def:$lineno): Helper with name '$helper' is already defined.\n"); + $orig_op = $m[1]; + if (!isset($opnames[$orig_op])) { + die("ERROR ($def:$lineno): Opcode with name '$orig_op' is not defined.\n"); } - $helpers[$helper] = array("op1"=>$op1,"op2"=>$op2,"param"=>null,"code"=>""); - $handler = null; - $list[$lineno] = array("helper"=>$helper); - } else if (strpos($line,"ZEND_VM_HELPER_EX(") === 0) { - // Parsing helper with parameter definition + $orig_code = $opnames[$orig_op]; + $condition = $m[2]; + $code = $extra_num++; + $op = $m[3]; + $op1 = parse_operand_spec($def, $lineno, $m[4], $flags1); + $op2 = parse_operand_spec($def, $lineno, $m[5], $flags2); + $flags = $flags1 | ($flags2 << 8); + if (!empty($m[7])) { + $flags |= parse_ext_spec($def, $lineno, $m[7]); + } + + if (isset($opcodes[$code])) { + die("ERROR ($def:$lineno): Opcode with name '$code' is already defined.\n"); + } + $opcodes[$orig_code]['type_spec'][$code] = $condition; + $used_extra_spec["TYPE"] = 1; + $opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>"","flags"=>$flags); + if (isset($m[9])) { + $opcodes[$code]["spec"] = parse_spec_rules($def, $lineno, $m[9]); + if (isset($opcodes[$code]["spec"]["NO_CONST_CONST"])) { + $opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_NO_CONST_CONST"]; + } + if (isset($opcodes[$code]["spec"]["COMMUTATIVE"])) { + $opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_COMMUTATIVE"]; + } + } + $opnames[$op] = $code; + $handler = $code; + $helper = null; + $list[$lineno] = array("handler"=>$handler); + } else if (strpos($line,"ZEND_VM_HELPER(") === 0 || strpos($line,"ZEND_VM_INLINE_HELPER(") === 0) { + // Parsing helper's definition if (preg_match( - "/^ZEND_VM_HELPER_EX\(\s*([A-Za-z_]+)\s*,\s*([A-Z|]+)\s*,\s*([A-Z|]+)\s*,\s*(.*)\s*\)/", + "/^ZEND_VM(_INLINE)?_HELPER\(\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(?:,\s*([^)]*))?\s*\)/", $line, $m) == 0) { die("ERROR ($def:$lineno): Invalid ZEND_VM_HELPER definition.\n"); } - $helper = $m[1]; - $op1 = array_flip(explode("|",$m[2])); - $op2 = array_flip(explode("|",$m[3])); - $param = $m[4]; + $inline = !empty($m[1]); + $helper = $m[2]; + $op1 = parse_operand_spec($def, $lineno, $m[3], $flags1); + $op2 = parse_operand_spec($def, $lineno, $m[4], $flags2); + $param = isset($m[5]) ? $m[5] : null; if (isset($helpers[$helper])) { die("ERROR ($def:$lineno): Helper with name '$helper' is already defined.\n"); } - // Store parameter - $params[$param] = 1; + // Store parameters + foreach (explode(",", $param) as $p) { + $p = trim($p); + if ($p !== "") { + $params[$p] = 1; + } + } - $helpers[$helper] = array("op1"=>$op1,"op2"=>$op2,"param"=>$param,"code"=>""); + $helpers[$helper] = array("op1"=>$op1,"op2"=>$op2,"param"=>$param,"code"=>"","inline"=>$inline); $handler = null; $list[$lineno] = array("helper"=>$helper); } else if (strpos($line,"ZEND_VM_EXPORT_HANDLER(") === 0) { @@ -1493,16 +2106,29 @@ function gen_vm($def, $skel) { fputs($f, "#define ZEND_VM_KIND_GOTO\t" . ZEND_VM_KIND_GOTO . "\n"); fputs($f, "#define ZEND_VM_KIND\t\t" . $GLOBALS["vm_kind_name"][ZEND_VM_KIND] . "\n"); fputs($f, "\n"); + foreach($vm_op_flags as $name => $val) { + fprintf($f, "#define %-24s 0x%08x\n", $name, $val); + } + fputs($f, "#define ZEND_VM_OP1_FLAGS(flags) (flags & 0xff)\n"); + fputs($f, "#define ZEND_VM_OP2_FLAGS(flags) ((flags >> 8) & 0xff)\n"); + fputs($f, "\n"); fputs($f, "BEGIN_EXTERN_C()\n\n"); - fputs($f, "ZEND_API const char *zend_get_opcode_name(zend_uchar opcode);\n\n"); + fputs($f, "ZEND_API const char *zend_get_opcode_name(zend_uchar opcode);\n"); + fputs($f, "ZEND_API uint32_t zend_get_opcode_flags(zend_uchar opcode);\n\n"); fputs($f, "END_EXTERN_C()\n\n"); foreach ($opcodes as $code => $dsc) { $code = str_pad((string)$code,$code_len," ",STR_PAD_LEFT); $op = str_pad($dsc["op"],$max_opcode_len); - fputs($f,"#define $op $code\n"); + if ($code <= $max_opcode) { + fputs($f,"#define $op $code\n"); + } } + $code = str_pad((string)$max_opcode,$code_len," ",STR_PAD_LEFT); + $op = str_pad("ZEND_VM_LAST_OPCODE",$max_opcode_len); + fputs($f,"\n#define $op $code\n"); + fputs($f, "\n#endif\n"); fclose($f); echo "zend_vm_opcodes.h generated successfully.\n"; @@ -1515,14 +2141,24 @@ function gen_vm($def, $skel) { fputs($f,"#include <stdio.h>\n"); fputs($f,"#include <zend.h>\n\n"); - fputs($f,"const char *zend_vm_opcodes_map[".($max_opcode + 1)."] = {\n"); + fputs($f,"static const char *zend_vm_opcodes_names[".($max_opcode + 1)."] = {\n"); for ($i = 0; $i <= $max_opcode; $i++) { fputs($f,"\t".(isset($opcodes[$i]["op"])?'"'.$opcodes[$i]["op"].'"':"NULL").",\n"); } fputs($f, "};\n\n"); + fputs($f,"static uint32_t zend_vm_opcodes_flags[".($max_opcode + 1)."] = {\n"); + for ($i = 0; $i <= $max_opcode; $i++) { + fprintf($f, "\t0x%08x,\n", isset($opcodes[$i]["flags"]) ? $opcodes[$i]["flags"] : 0); + } + fputs($f, "};\n\n"); + fputs($f, "ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) {\n"); - fputs($f, "\treturn zend_vm_opcodes_map[opcode];\n"); + fputs($f, "\treturn zend_vm_opcodes_names[opcode];\n"); + fputs($f, "}\n"); + + fputs($f, "ZEND_API uint32_t zend_get_opcode_flags(zend_uchar opcode) {\n"); + fputs($f, "\treturn zend_vm_opcodes_flags[opcode];\n"); fputs($f, "}\n"); fclose($f); @@ -1574,31 +2210,61 @@ function gen_vm($def, $skel) { gen_executor($f, $skl, ZEND_VM_SPEC, ZEND_VM_KIND, "execute", "zend_init_opcodes_handlers"); // Generate zend_vm_get_opcode_handler() function + out($f, "static const void *zend_vm_get_opcode_handler_ex(uint32_t spec, const zend_op* op)\n"); + out($f, "{\n"); + if (!ZEND_VM_SPEC) { + out($f, "\treturn zend_opcode_handlers[spec];\n"); + } else { + out($f, "\tstatic const int zend_vm_decode[] = {\n"); + out($f, "\t\t_UNUSED_CODE, /* 0 */\n"); + out($f, "\t\t_CONST_CODE, /* 1 = IS_CONST */\n"); + out($f, "\t\t_TMP_CODE, /* 2 = IS_TMP_VAR */\n"); + out($f, "\t\t_UNUSED_CODE, /* 3 */\n"); + out($f, "\t\t_VAR_CODE, /* 4 = IS_VAR */\n"); + out($f, "\t\t_UNUSED_CODE, /* 5 */\n"); + out($f, "\t\t_UNUSED_CODE, /* 6 */\n"); + out($f, "\t\t_UNUSED_CODE, /* 7 */\n"); + out($f, "\t\t_UNUSED_CODE, /* 8 = IS_UNUSED */\n"); + out($f, "\t\t_UNUSED_CODE, /* 9 */\n"); + out($f, "\t\t_UNUSED_CODE, /* 10 */\n"); + out($f, "\t\t_UNUSED_CODE, /* 11 */\n"); + out($f, "\t\t_UNUSED_CODE, /* 12 */\n"); + out($f, "\t\t_UNUSED_CODE, /* 13 */\n"); + out($f, "\t\t_UNUSED_CODE, /* 14 */\n"); + out($f, "\t\t_UNUSED_CODE, /* 15 */\n"); + out($f, "\t\t_CV_CODE /* 16 = IS_CV */\n"); + out($f, "\t};\n"); + out($f, "\tuint32_t offset = 0;\n"); + out($f, "\tif (spec & SPEC_RULE_OP1) offset = offset * 5 + zend_vm_decode[op->op1_type];\n"); + out($f, "\tif (spec & SPEC_RULE_OP2) offset = offset * 5 + zend_vm_decode[op->op2_type];\n"); + if (isset($used_extra_spec["OP_DATA"])) { + out($f, "\tif (spec & SPEC_RULE_OP_DATA) offset = offset * 5 + zend_vm_decode[(op + 1)->op1_type];\n"); + } + if (isset($used_extra_spec["RETVAL"])) { + out($f, "\tif (spec & SPEC_RULE_RETVAL) offset = offset * 2 + (op->result_type != IS_UNUSED);\n"); + } + if (isset($used_extra_spec["QUICK_ARG"])) { + out($f, "\tif (spec & SPEC_RULE_QUICK_ARG) offset = offset * 2 + (op->op2.num < MAX_ARG_FLAG_NUM);\n"); + } + if (isset($used_extra_spec["SMART_BRANCH"])) { + out($f, "\tif (spec & SPEC_RULE_SMART_BRANCH) {\n"); + out($f, "\t\toffset = offset * 3;\n"); + out($f, "\t\tif ((op+1)->opcode == ZEND_JMPZ) {\n"); + out($f, "\t\t\toffset += 1;\n"); + out($f, "\t\t} else if ((op+1)->opcode == ZEND_JMPNZ) {\n"); + out($f, "\t\t\toffset += 2;\n"); + out($f, "\t\t}\n"); + out($f, "\t}\n"); + } + out($f, "\treturn zend_opcode_handlers[(spec & SPEC_START_MASK) + offset];\n"); + } + out($f, "}\n\n"); out($f, "static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op)\n"); out($f, "{\n"); if (!ZEND_VM_SPEC) { - out($f, "\treturn zend_opcode_handlers[opcode];\n"); + out($f, "\treturn zend_vm_get_opcode_handler_ex(opcode, op);\n"); } else { - out($f, "\t\tstatic const int zend_vm_decode[] = {\n"); - out($f, "\t\t\t_UNUSED_CODE, /* 0 */\n"); - out($f, "\t\t\t_CONST_CODE, /* 1 = IS_CONST */\n"); - out($f, "\t\t\t_TMP_CODE, /* 2 = IS_TMP_VAR */\n"); - out($f, "\t\t\t_UNUSED_CODE, /* 3 */\n"); - out($f, "\t\t\t_VAR_CODE, /* 4 = IS_VAR */\n"); - out($f, "\t\t\t_UNUSED_CODE, /* 5 */\n"); - out($f, "\t\t\t_UNUSED_CODE, /* 6 */\n"); - out($f, "\t\t\t_UNUSED_CODE, /* 7 */\n"); - out($f, "\t\t\t_UNUSED_CODE, /* 8 = IS_UNUSED */\n"); - out($f, "\t\t\t_UNUSED_CODE, /* 9 */\n"); - out($f, "\t\t\t_UNUSED_CODE, /* 10 */\n"); - out($f, "\t\t\t_UNUSED_CODE, /* 11 */\n"); - out($f, "\t\t\t_UNUSED_CODE, /* 12 */\n"); - out($f, "\t\t\t_UNUSED_CODE, /* 13 */\n"); - out($f, "\t\t\t_UNUSED_CODE, /* 14 */\n"); - out($f, "\t\t\t_UNUSED_CODE, /* 15 */\n"); - out($f, "\t\t\t_CV_CODE /* 16 = IS_CV */\n"); - out($f, "\t\t};\n"); - out($f, "\t\treturn zend_opcode_handlers[opcode * 25 + zend_vm_decode[op->op1_type] * 5 + zend_vm_decode[op->op2_type]];\n"); + out($f, "\treturn zend_vm_get_opcode_handler_ex(zend_spec_handlers[opcode], op);\n"); } out($f, "}\n\n"); @@ -1608,6 +2274,55 @@ function gen_vm($def, $skel) { out($f, "\top->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], op);\n"); out($f, "}\n\n"); + // Generate zend_vm_set_opcode_handler_ex() function + out($f, "ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint32_t op2_info, uint32_t res_info)\n"); + out($f, "{\n"); + out($f, "\tzend_uchar opcode = zend_user_opcodes[op->opcode];\n"); + if (!ZEND_VM_SPEC) { + out($f, "\top->handler = zend_vm_get_opcode_handler_ex(opcode, op);\n"); + } else { + out($f, "\tuint32_t spec = zend_spec_handlers[opcode];\n"); + if (isset($used_extra_spec["TYPE"])) { + out($f, "\tswitch (opcode) {\n"); + foreach($opcodes as $code => $dsc) { + if (isset($dsc['type_spec'])) { + $orig_op = $dsc['op']; + out($f, "\t\tcase $orig_op:\n"); + $first = true; + foreach($dsc['type_spec'] as $code => $condition) { + if ($first) { + out($f, "\t\t\tif ($condition) {\n"); + $first = false; + } else { + out($f, "\t\t\t} else if ($condition) {\n"); + } + $spec_dsc = $opcodes[$code]; + if (isset($spec_dsc["spec"]["NO_CONST_CONST"])) { + out($f, "\t\t\t\tif (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {\n"); + out($f, "\t\t\t\t\tbreak;\n"); + out($f, "\t\t\t\t}\n"); + } + out($f, "\t\t\t\tspec = ${spec_dsc['spec_code']};\n"); + if (isset($spec_dsc["spec"]["COMMUTATIVE"])) { + out($f, "\t\t\t\tif (op->op1_type > op->op2_type) {\n"); + out($f, "\t\t\t\t\tzend_swap_operands(op);\n"); + out($f, "\t\t\t\t}\n"); + } + } + if (!$first) { + out($f, "\t\t\t}\n"); + } + out($f, "\t\t\tbreak;\n"); + } + } + out($f, "\t\tdefault:\n"); + out($f, "\t\t\tbreak;\n"); + out($f, "\t}\n"); + } + out($f, "\top->handler = zend_vm_get_opcode_handler_ex(spec, op);\n"); + } + out($f, "}\n\n"); + // Generate zend_vm_call_opcode_handler() function if (ZEND_VM_KIND == ZEND_VM_KIND_CALL) { out($f, "ZEND_API int zend_vm_call_opcode_handler(zend_execute_data* ex)\n"); diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index e42c2e22f5..d4c76ad265 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -21,7 +21,7 @@ #include <stdio.h> #include <zend.h> -const char *zend_vm_opcodes_map[173] = { +static const char *zend_vm_opcodes_names[184] = { "ZEND_NOP", "ZEND_ADD", "ZEND_SUB", @@ -195,8 +195,209 @@ const char *zend_vm_opcodes_map[173] = { "ZEND_SPACESHIP", "ZEND_DECLARE_ANON_CLASS", "ZEND_DECLARE_ANON_INHERITED_CLASS", + "ZEND_FETCH_STATIC_PROP_R", + "ZEND_FETCH_STATIC_PROP_W", + "ZEND_FETCH_STATIC_PROP_RW", + "ZEND_FETCH_STATIC_PROP_IS", + "ZEND_FETCH_STATIC_PROP_FUNC_ARG", + "ZEND_FETCH_STATIC_PROP_UNSET", + "ZEND_UNSET_STATIC_PROP", + "ZEND_ISSET_ISEMPTY_STATIC_PROP", + "ZEND_FETCH_CLASS_CONSTANT", + "ZEND_BIND_LEXICAL", + "ZEND_BIND_STATIC", +}; + +static uint32_t zend_vm_opcodes_flags[184] = { + 0x00000000, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000007, + 0x00000007, + 0x00000707, + 0x00000303, + 0x00000303, + 0x00000707, + 0x00000707, + 0x00000707, + 0x00000707, + 0x07000003, + 0x00000003, + 0x04006751, + 0x04006751, + 0x04006751, + 0x04006751, + 0x04006751, + 0x04006751, + 0x04006751, + 0x04006751, + 0x04006751, + 0x04006751, + 0x04006751, + 0x00000001, + 0x00000001, + 0x00000001, + 0x00000001, + 0x00000301, + 0x0b000101, + 0x00000007, + 0x00000000, + 0x00000020, + 0x00002007, + 0x00002007, + 0x03002007, + 0x00002007, + 0x00002007, + 0x00000707, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000007, + 0x00000707, + 0x01000701, + 0x01000701, + 0x01000701, + 0x00000000, + 0x00000001, + 0x01000300, + 0x00000000, + 0x01000310, + 0x00000003, + 0x00000010, + 0x00000310, + 0x00001003, + 0x00001001, + 0x00001001, + 0x01000073, + 0x01000300, + 0x00004005, + 0x00186703, + 0x00106703, + 0x08000007, + 0x00030107, + 0x00000751, + 0x00000751, + 0x00002003, + 0x03000001, + 0x00000007, + 0x00010107, + 0x00000707, + 0x00000753, + 0x00010107, + 0x00006701, + 0x00000751, + 0x00010107, + 0x00006701, + 0x00000751, + 0x00010107, + 0x00000707, + 0x00000757, + 0x00050107, + 0x01006703, + 0x01000753, + 0x00010107, + 0x00000701, + 0x00000751, + 0x00000707, + 0x06000301, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x01000000, + 0x0c001001, + 0x03000103, + 0x00000003, + 0x05000700, + 0x00000057, + 0x0b000003, + 0x01000757, + 0x01008773, + 0x00030107, + 0x00020757, + 0x00001003, + 0x00001001, + 0x01000703, + 0x00000000, + 0x00001001, + 0x00000007, + 0x00000003, + 0x07000003, + 0x00000103, + 0x00002003, + 0x03000001, + 0x00004005, + 0x01000700, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000751, + 0x00000751, + 0x00000751, + 0x00000751, + 0x00000751, + 0x00000000, + 0x00007305, + 0x00000000, + 0x00000100, + 0x00000000, + 0x00000003, + 0x00000303, + 0x00000300, + 0x00000100, + 0x00000000, + 0x00006701, + 0x00020757, + 0x00000000, + 0x00000000, + 0x00002000, + 0x00002003, + 0x00000103, + 0x00000000, + 0x00000000, + 0x00000101, + 0x05000000, + 0x00000000, + 0x00000000, + 0x0b000303, + 0x00000003, + 0x09003020, + 0x0a003000, + 0x00000010, + 0x00000000, + 0x00000707, + 0x04006751, + 0x00000301, + 0x00002003, + 0x00000707, + 0x03000000, + 0x03000100, + 0x00007307, + 0x00007307, + 0x00007307, + 0x00007307, + 0x01007307, + 0x00007307, + 0x00007307, + 0x00027307, + 0x00000373, + 0x00100101, + 0x00100301, }; ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) { - return zend_vm_opcodes_map[opcode]; + return zend_vm_opcodes_names[opcode]; +} +ZEND_API uint32_t zend_get_opcode_flags(zend_uchar opcode) { + return zend_vm_opcodes_flags[opcode]; } diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 9ba87e58be..90f2ea4e51 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -28,9 +28,45 @@ #define ZEND_VM_KIND_GOTO 3 #define ZEND_VM_KIND ZEND_VM_KIND_CALL +#define ZEND_VM_OP_SPEC 0x00000001 +#define ZEND_VM_OP_CONST 0x00000002 +#define ZEND_VM_OP_TMPVAR 0x00000004 +#define ZEND_VM_OP_TMPVARCV 0x00000008 +#define ZEND_VM_OP_MASK 0x000000f0 +#define ZEND_VM_OP_NUM 0x00000010 +#define ZEND_VM_OP_JMP_ADDR 0x00000020 +#define ZEND_VM_OP_TRY_CATCH 0x00000030 +#define ZEND_VM_OP_LIVE_RANGE 0x00000040 +#define ZEND_VM_OP_THIS 0x00000050 +#define ZEND_VM_OP_NEXT 0x00000060 +#define ZEND_VM_OP_CLASS_FETCH 0x00000070 +#define ZEND_VM_OP_CONSTRUCTOR 0x00000080 +#define ZEND_VM_EXT_VAR_FETCH 0x00010000 +#define ZEND_VM_EXT_ISSET 0x00020000 +#define ZEND_VM_EXT_ARG_NUM 0x00040000 +#define ZEND_VM_EXT_ARRAY_INIT 0x00080000 +#define ZEND_VM_EXT_REF 0x00100000 +#define ZEND_VM_EXT_MASK 0x0f000000 +#define ZEND_VM_EXT_NUM 0x01000000 +#define ZEND_VM_EXT_JMP_ADDR 0x03000000 +#define ZEND_VM_EXT_DIM_OBJ 0x04000000 +#define ZEND_VM_EXT_CLASS_FETCH 0x05000000 +#define ZEND_VM_EXT_CONST_FETCH 0x06000000 +#define ZEND_VM_EXT_TYPE 0x07000000 +#define ZEND_VM_EXT_EVAL 0x08000000 +#define ZEND_VM_EXT_FAST_CALL 0x09000000 +#define ZEND_VM_EXT_FAST_RET 0x0a000000 +#define ZEND_VM_EXT_SRC 0x0b000000 +#define ZEND_VM_EXT_SEND 0x0c000000 +#define ZEND_VM_NO_CONST_CONST 0x40000000 +#define ZEND_VM_COMMUTATIVE 0x80000000 +#define ZEND_VM_OP1_FLAGS(flags) (flags & 0xff) +#define ZEND_VM_OP2_FLAGS(flags) ((flags >> 8) & 0xff) + BEGIN_EXTERN_C() ZEND_API const char *zend_get_opcode_name(zend_uchar opcode); +ZEND_API uint32_t zend_get_opcode_flags(zend_uchar opcode); END_EXTERN_C() @@ -202,5 +238,18 @@ END_EXTERN_C() #define ZEND_SPACESHIP 170 #define ZEND_DECLARE_ANON_CLASS 171 #define ZEND_DECLARE_ANON_INHERITED_CLASS 172 +#define ZEND_FETCH_STATIC_PROP_R 173 +#define ZEND_FETCH_STATIC_PROP_W 174 +#define ZEND_FETCH_STATIC_PROP_RW 175 +#define ZEND_FETCH_STATIC_PROP_IS 176 +#define ZEND_FETCH_STATIC_PROP_FUNC_ARG 177 +#define ZEND_FETCH_STATIC_PROP_UNSET 178 +#define ZEND_UNSET_STATIC_PROP 179 +#define ZEND_ISSET_ISEMPTY_STATIC_PROP 180 +#define ZEND_FETCH_CLASS_CONSTANT 181 +#define ZEND_BIND_LEXICAL 182 +#define ZEND_BIND_STATIC 183 + +#define ZEND_VM_LAST_OPCODE 183 #endif |
